An overview of the

There are two types of refresh schemes used in projects, commonly referred to as hot updates and hot overloads in order to distinguish them

  • Hot reload: Reloads as the name implies, usingwindow.location.reload()Refresh the interface for the purpose of updating
  • Hot update: Updates only the modified files. The screen will not be refreshed.

Hot Module Replacement (or HMR) is one of the most useful features webPack provides. It allows various modules to be updated at run time without a complete refresh. – the official website

Both hot reloading and hot updating can greatly improve our development efficiency. The following will sort out the knowledge points of thermal update from shallow to deep, and the related knowledge of thermal overload is relatively simple, which will be mentioned in the explanation of thermal update.

Understand the value of hot updates

In my daily work, after understanding the mechanism of hot update, I will find opportunities in the following aspects.

  • Build your own project inwebpackUse in configuration
  • Build your own CLI, will ownwebpackThe configuration is encapsulated in the CLI. For details, seevue-cli.
  • When building their own SSR framework, refer toNuxt.
  • Interview for a raise, get to the top of your game.

Implementation of hot update

It is suggested to read the knowledge related to the official website first when reading the following contents. The following contents are explained based on the information of the official website.

This article does not repeat the official website above the relevant knowledge. The following is an extension of the process of building HMR through node.js API.

The official website uses Webpack Dev Server and Node.js API to build HMR. In order to better understand the principle of HMR, Here we use the further Middleware plugin and node.js API to implement HMR.

Let’s start with a quick look at some of the middleware and plugins you’ll need

  • Webpack-hot-middleware: This module focuses only on the mechanism for connecting a browser client to a Webpack server and receiving updates.
  • Webpack-dev-middleware: A wrapper that passes Webpack-processed files to a server.
  • Webpack. HotModuleReplacementPlugin: used to generate the hot update relevant documents.

Let’s actually combine the Middleware and plugin to implement HMR. First of all, based on the example on the official website, we create the github address of the directory specific code as shown below

├ ─ package. Json ├ ─ yarn. The lock ├ ─ SRC | ├ ─ but js - with an example of website | └ print. Js ├ ─ server | └ dev - server. Js ├ ─ bundle | └ webpack. Config. JsCopy the code

package.json

		"express": "^ 4.17.1"."html-webpack-plugin": "^ 5.3.1"."webpack": "^ 5.39.1"."webpack-cli": "^ 4.7.2." "."webpack-dev-middleware": "^ 5.0.0"."webpack-hot-middleware": "^ 2.25.0"
Copy the code

webpack.config.js

const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    mode: "development".entry: {
       index: './src/index.js',},output: {
        filename: '[name].bundle.js'.path: path.resolve(__dirname, '.. /dist'),
        clean: true,},plugins: [
      new HtmlWebpackPlugin(),
    ]
  };

Copy the code

dev-server.js

const config = require(".. /bundle/webpack.config"); 
const express = require('express');
const app = express();
const webpack = require("webpack");

// The current environment is development environment
// Modify the entry file for hot update communication
config.entry.index = ["webpack-hot-middleware/client", config.entry.index];
// Use lasthash.hot-update. json and chunkid.lasthash.hot-update.js with generated hot updates
config.plugins.push(new webpack.HotModuleReplacementPlugin());
// Start compiling after the hot update environment is ready
const compiler = webpack(config);
// Webpack-dev-Middleware is a wrapper that sends webPack-processed files to a server.
const devMiddleware = require("webpack-dev-middleware")(compiler, {
    publicPath: config.output.publicPath,
    serverSideRender: true 
});

app.use(devMiddleware)

app.use(require("webpack-hot-middleware")(compiler));
compiler.hooks.done.tap("done".stats= > {
    const info = stats.toJson();
    if (stats.hasWarnings()) {
        console.warn(info.warnings);
    }

    if (stats.hasErrors()) {
        console.error(info.errors);
        return;
    }
    console.log("Packed and ready");
});

app.listen(9527.() = > {
    console.log("Your app is running".9527);
});
Copy the code

At this time, we have realized the HMR similar to the official website. Now we will talk about the principles of HRM based on this demo.

The principle of hot renewal

Hot updates at compile time and in the interface

When we compile it, we can see it generated intuitively

index.37b9afad78a811b0d250.hot-update.js

index.37b9afad78a811b0d250.hot-update.json

The two withHMR Two related files.



On the browser, two requests were sent

Used to retrieve the two files respectively.

The following is returned

index.37b9afad78a811b0d250.hot-update.json

{"c": ["index"]."r": []."m": []}Copy the code

index.37b9afad78a811b0d250.hot-update.js


self["webpackHotUpdateuse"] ("index", {
    "./src/print.js":
    ((__unused_webpack_module, __webpack_exports__, __webpack_require__) = > {
        "use strict";
        __webpack_require__.r(__webpack_exports__);
        __webpack_require__.d(__webpack_exports__, {
            "default": () = > (/* binding */ printMe)});
            function printMe() {
                console.log('Updating print.js2.. ');
            }//# sourceURL=webpack://use/./src/print.js?" );
    })},
     function(__webpack_require__) {
     "use strict";
        (() = > {
            __webpack_require__.h = () = > ("f4e40048658a6c48ff32")}) (); });Copy the code

After seeing the above phenomenon, there are probably a lot of doubts, with these doubts continue to look below.

Explain the principle of hot update

With the above questions, let’s explore the meaning of hot update. First, let’s take a look at the overall process of hot update

  1. First startdev-serverTo the presentoptions.entryInsert related toSSERelevant code.

The HTML 5 server sent event (SSE) and heartbeat detection mechanism are mainly used for communication between the server and the client. When the server file changes, it can be easily notified to the client.

  1. Listening to thewebpack donecompiler.hooks.done.tapNode fromstatsTo get the latesthashValue, passed to the client, if you just do the hot overload to this step can be finished, usewindow.location.reload();
  2. Client AcquisitionlastHash.hot-update.jsonFile to get the chunkId of the currently updated file.
  3. Based on the current updatechunkIdTo pick upchunkID.lastHash.hot-update.jsfile
  4. performwebpackHotUpdate, from the existingcacheFind the old data information corresponding to the current chunkId, update and execute the current latestchunkCode for easy updatescache, then execute the correspondinghot.acceptCode to implementrenderOperation.

conclusion

This article does not use webpackDevServer, which comes with webPack-dev-Middleware and Express servers. And use Websocket to replace SSE to realize webpack-hot-middleware logic. The principle part also helps you to understand HMR as a whole. I hope that through this article, you can use the hot update, if you need to understand the details of each step, you can follow this idea to look at the source code.