Webpack HMR process summary

  • webpack-dev-middleware:
    • It mainly reads the static resource file back to the browser
  • webpack-hot-middleware:
    • Content-type is returned after matching/webpack_hMR routestext/event-stream; charset=utf-8The response of the
  • webpack-hot-middleware/client.js:new EventSource(‘/ webpack_hMR ‘) listens for messages that are actively pushed by the server, such as hash values and changed modules, to be processed by./process-update.js
  • webpack-hot-middleware/process-update.js: perform module. Hot. Check (), equivalent to call HotModuleReplacement. The runtime hotCheck (); Then call hotDownloadManifest to get the JSON filePrevious hash.hot-update.json, the returned content is
{"h":"fb3e9ba6fcd4f92f416c"."c": {"app":true}}
Copy the code
// Bundle.js defines some functions
function hotDownloadManifest(requestTimeout) {
    / * * * * * * /
    requestTimeout = requestTimeout || 10000;
    / * * * * * * /
    return new Promise(function (resolve, reject) {
      / * * * * * * /
      if (typeof XMLHttpRequest === "undefined") {
        / * * * * * * /
        return reject(new Error("No browser support"));
        / * * * * * * /
      }
      / * * * * * * /
      try {
        / * * * * * * /
        var request = new XMLHttpRequest();
        / * * * * * * /
        var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json";
        / * * * * * * /
        request.open("GET", requestPath, true);
        / * * * * * * /
        request.timeout = requestTimeout;
        / * * * * * * /
        request.send(null);
        / * * * * * * /
      } catch (err) {
        / * * * * * * /
        return reject(err);
        / * * * * * * /
      }
      / * * * * * * /
      request.onreadystatechange = function () {
        / * * * * * * /
        if(request.readyState ! = =4)
          return;
        / * * * * * * /
        if (request.status === 0) {
          / * * * * * * /
          // timeout
          / * * * * * * /
          reject(/ * * * * * * /
            new Error("Manifest request to " + requestPath + " timed out.")/ * * * * * * /
          );
          / * * * * * * /
        } else if (request.status === 404) {
          / * * * * * * /
          // no update available
          / * * * * * * /
          resolve();
          / * * * * * * /
        } else if(request.status ! = =200&& request.status ! = =304) {
          / * * * * * * /
          // other failure
          / * * * * * * /
          reject(new Error("Manifest request to " + requestPath + " failed."));
          / * * * * * * /
        } else {
          / * * * * * * /
          // success
          / * * * * * * /
          try {
            / * * * * * * /
            var update = JSON.parse(request.responseText);
            / * * * * * * /
          } catch (e) {
            / * * * * * * /
            reject(e);
            / * * * * * * /
            return;
            / * * * * * * /
          }
          / * * * * * * /
          resolve(update);
          / * * * * * * /
        }
        / * * * * * * /};/ * * * * * * /});/ * * * * * * /
  }
  
  
Copy the code

Then call hotEnsureUpdateChunk()->hotDownloadUpdateChunk() to request the last hash.hot-update.js return a jSONp function to execute immediately

// bundler.js

function hotEnsureUpdateChunk(chunkId) {
    / * * * * * * /
    if(! hotAvailableFilesMap[chunkId]) {/ * * * * * * /
      hotWaitingFilesMap[chunkId] = true;
      / * * * * * * /
    } else {
      / * * * * * * /
      hotRequestedFilesMap[chunkId] = true;
      / * * * * * * /
      hotWaitingFiles++;
      / * * * * * * /
      hotDownloadUpdateChunk(chunkId);
      / * * * * * * /
    }
    / * * * * * * /
  }
  
 function hotDownloadUpdateChunk(chunkId) {
    / * * * * * * /
    var script = document.createElement("script");
    / * * * * * * /
    script.charset = "utf-8";
    / * * * * * * /
    script.src = __webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js";
    / * * * * * * /
    if (null)
      script.crossOrigin = null;
    / * * * * * * /
    document.head.appendChild(script);
    / * * * * * * /
  }
Copy the code
// app.e75837e14d1a14baef6f.hot-update.js

webpackHotUpdate("app", {

    / * * * /
    ". / node_modules / _vue - [email protected] @ vue - loader/lib/template - the compiler/index. Js? {\"id\":\"data-v-4a0103ec\",\"hasScoped\":true,\"optionsId\":\"0\",\"buble\":{\"transforms\":{}}}! . / node_modules / _vue - [email protected] @ vue - loader/lib/selector. Js? type=template&index=0! ./example/pages/button.vue": / *! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *! * \! * * *. / node_modules / _vue - [email protected] @ vue - loader/lib/template - the compiler? {"id":"data-v-4a0103ec","hasScoped":true,"optionsId":"0","buble":{"transforms":{}}}! . / node_modules / _vue - [email protected] @ vue - loader/lib/selector. Js? type=template&index=0! ./example/pages/button.vue ***! A \ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
    / *! exports provided: render, staticRenderFns */
    / * * * /
    (function(module, __webpack_exports__, __webpack_require__) {

        "use strict";
        __webpack_require__.r(__webpack_exports__);
        /* harmony export (binding) */
        __webpack_require__.d(__webpack_exports__, "render".function() {
            return render;
        });
        /* harmony export (binding) */
        __webpack_require__.d(__webpack_exports__, "staticRenderFns".function() {
            return staticRenderFns;
        });
        var render = function() {
            var _vm = this
            var _h = _vm.$createElement
            var _c = _vm._self._c || _h
            return _c("div", [_vm._v("3")])}var staticRenderFns = []
        render._withStripped = true

        if (true) {
            module.hot.accept()
            if (module.hot.data) {
                __webpack_require__(/ *! vue-loader/node_modules/vue-hot-reload-api */
                ". / node_modules / _vue - [email protected] @ vue - hot - reload - API/dist/index. Js. "").rerender("data-v-4a0103ec", {
                    render: render,
                    staticRenderFns: staticRenderFns
                })
            }
        }

        / * * * /})})Copy the code
// bundle.js
 var parentHotUpdateCallback = window["webpackHotUpdate"];
  / * * * * * * /
  window["webpackHotUpdate"] = // eslint-disable-next-line no-unused-vars
    / * * * * * * /
    function webpackHotUpdateCallback(chunkId, moreModules) {
      / * * * * * * /
      hotAddUpdateChunk(chunkId, moreModules);
      / * * * * * * /
      if (parentHotUpdateCallback)
        parentHotUpdateCallback(chunkId, moreModules);
      / * * * * * * /
    }
Copy the code