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 routes
text/event-stream; charset=utf-8
The response of the
- Content-type is returned after matching/webpack_hMR routes
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.jswebpack-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