LiveReloading

This is the seventh day of my participation in the August More text Challenge. For details, see:August is more challenging

After each change, we need to manually compile and package before we can see what is actually packaged

This process often affects our development efficiency. We hope that when the file changes, it can be compiled and displayed automatically

There are three implementation methods:

  1. webpack watch mode
  2. webpack-dev-server
  3. webpack-dev-middleware

webpack watch mode

Webpack provides us with watch mode, in which all the files in the Webpack dependency diagram will be recompiled as soon as one of them is updated, so we don’t need to manually run the NPM run build directive

There are two ways to start the Watch

  1. In the exported configuration, add watch: true

webpack.config.js

odule.exports = {
  mode: 'development'.watch: true.entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'}}Copy the code
  1. Add the –watch logo to the command to start Webpack

package.json

"scripts": {
  "build": "webpack"."watch": "webpack --watch"
}
Copy the code

webpack-dev-server

There are some problems with using Watch for code listening:

  1. Watch can only compile code in real time, and it can’t start a local service to run our code,

    Let’s see if we can live reloading.

  2. When compiled successfully, a new folder will be formed, which means file stystem will be frequently manipulated,

    In fact, we just need to produce the packaging folder when the project is fully written

  3. When code is compiled using watch, the entire page is refreshed, and there is no way to preserve some of the state of the page

  4. Watch compiles the file, compiling the entire source code regardless of changes

We can use Webpack-dev-server (or WDR for short) for optimization

The installation

#The installation
npm i webpack-dev-server -D
Copy the code

perform

package.json

"scripts": {
  "serve": "webpack serve"
}
Copy the code

By default webpack-dev-server is running on port 8080. If you do not need to change the configuration of webpack-dev-server, you do not need to do any configuration in webpack.config.js. Simply perform WebPack Serve and WebPack will automatically help us call Webpack-dev-server

Webpack-dev-server uses a library called memfs internally to load our packaged folders directly into memory. You do not need to operate the file system frequently to improve compilation efficiency

webpack-dev-middleware

By default, webpack-dev-server internally uses Express to set up a local server and enable local services for us.

However, if you need to customize the middleware, you can use webpack-dev-middleware

Webpack-dev-middleware is a wrapper that sends WebPack-processed files to a server

Webpack-dev-server uses webpack-dev-middleware internally,

However, it can also be used as a separate package for more customization as required;

#In this case, express, but you can also use other tools like KOA
npm install --save-dev express webpack-dev-middleware
Copy the code

In the project root directory, create server.js,

const express = require('express')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpack = require('webpack')

// Create the server object
const app = express()

// Use the webpack function to load the configuration file and generate a WebPack compiler
const complier = webpack(require('./webpack.config'))

// webpack-dev-middleware turns Complire into middleware
const middleware = webpackDevMiddleware(complier)

// Use middleware
app.use(middleware)

// Start the service. At this point, you can customize the service as needed
app.listen(3000.() = > console.log('serve is running'))
Copy the code
#perform
node server.js
Copy the code

HMR

HMR is Hot Module Replacement, which translates to Hot Module Replacement

Module hot replacement refers to the process of replacing, adding, and removing modules while the application is running without having to refresh the entire page

HMR increases the speed of development in the following ways:

  1. The entire page is not reloaded so that some application state is not lost
  2. Update only what needs to change, saving development time
  3. Changes to CSS and JS source code are immediately updated in the browser, which is equivalent to modifying styles directly in the browser’s DevTools

By default, webpack-dev-server already supports HMR, we just need to enable it;

When we make changes to the source code without HMR enabled, the entire page is automatically refreshed using Live reloading

webpack.config.js

module.exports = {
  devServer: {
    hot: true}}Copy the code

At this point, when we modify the code of a certain module, the whole page is still refreshed

This is because we need to specify which modules will be HM when the update occurs

Index.js -- the main entry file

if (module.hot) {
  // Parameter 1: enable the HMR module path
  / / 2; The callback function that needs to be executed after the corresponding module has been updated
  module.hot.accept('./math.js'.() = > console.log('The math module sent an update'))
  module.hot.accept('./foo.js'.() = > console.log('Foo module sent an update'))}Copy the code
if (module.hot) {
  // The accept method also supports passing an array
  module.hot.accept(['./math.js'.'./foo.js'])}Copy the code

Configure the HMR in the framework

When developing other projects, it is often cumbersome to manually write the MODULE.hot. accpet API, but in fact the community has a mature solution for these:

For example, in vUE development, we use the Vue-Loader, which supports the HMR of the VUE component and provides the body out of the box

For example, in react development, there is react-refresh, which adjusts react components in real time

React

Previously, React used the React Hot Loader to implement HMR, but it has been changed to use react-Refresh

#@pmmmwh/ React-refresh -webpack-plugin is prefixed with @pmmmwh
#The @pmmMWh/React-refresh -webpack-plugin relies on the React-Refresh library for HMR
npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
Copy the code

configuration

webpack.config.js

const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')

module.exports = {
  devServer: {
    hot: true
  }, 

  plugins: [
    new ReactRefreshWebpackPlugin()
  ]
}
Copy the code

babel.config.js

module.exports = {
  presets: [
    '@babel/preset-env'.'@babel/preset-react'].plugins: [
    'react-refresh/babel']}Copy the code

Vue

#The installation
npm install vue-loader vue-template-compiler -D
Copy the code

webpack.config.js

To load Vue, we need to use Vue-Loader, and the components loaded by Vue-loader will help us to handle HMR by default

// The latest vue-loader is no longer required by require('vue-loader/lib/plugin')
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  devServer: {
    hot: true
  },

  module: {
    rules: [{test: /\.vue$/,
        use: 'vue-loader'}},plugins: [
    new VueLoaderPlugin()  
  ]
}
Copy the code

HMR principle

Webpack-dev-server creates two services: a static resource service (Express) and a Socket service (net.socket).

Express Server is responsible for serving static resources directly (the packaged resources are requested and parsed directly by the browser)

HMR Socket Server is a long connection of a Socket:

  1. One of the best benefits of a persistent connection is that both parties can communicate once the connection is established (the server can send files directly to the client, whereas HTTP requests must be made by the server actively).

  2. When the server hears that the corresponding module has changed,

    Json (the manifest file records the updated configuration information, such as the location information) and.js (the update chunk records the actual updated content) are generated.

  3. Through the long connection, you can directly send the two files to the client (browser) actively.

  4. The browser gets the two new files, loads them through the HMR Runtime mechanism (which webPack provides at the time of packaging), and updates them for the modified modules