preface
Many of you have used WebPack’s Hot Module Replacement, which allows the browser to see the changes in real time when we make them, meaning we don’t have to manually refresh the browser to see the changes. This is especially important in our development process.
- The principle of
When a source code changes, simply recompile the changed module and replace the corresponding module in the browser with the new output module.
Sounds simple, right? So let’s look at what it does in this process.
First, basic use
Open the function
First let’s learn how to use it. DevServer does not enable module hot replacement by default. There are two main ways to enable module hot replacement
- Start with the argument –hot. The full command is as follows
webpack-dev-server –hot
- Through access Plugin
Plugins: {/ / plug-in role is to implement module hot replacement new HotModuleReplacementPlugin (),} devServer: {hot: true}Copy the code
scope
In addition, we need to understand the scope of thermal renewal
- The style file
The HMR function can be used because style-loader is implemented internally. When we modify the CSS file, the following state will appear. We can see that the CSS file is clearly modified, and the browser will update the module locally
- Js file
HMR is disabled by default, and it will refresh the entire page instead of a partial refresh
If we need js files to also have HMR functionality, add the following code for the corresponding JS file, but note that this method can only handle other files that are not entry JS files
Module.hot.accept ('./index.js', function() {// If (module.hot) {// if (module.hot) {// if (module.hot) {// if (module.hot) {// if (module.hot) {// if (module.hot) {// if (module.hot) {// if (module. Other defaults do not repackage the build and execute subsequent callbacks})}Copy the code
- The HTML file
HTML files cannot be hotbrushed, and when we modify the HTML file, we do not partially update or refresh the browser.
If we need hot updates, adding HTML files to the entry can solve the problem
Two, principle analysis
The red box at the bottom of the image is the server side, and the orange box above is the browser side.
The green boxes are the areas controlled by the WebPack code. The blue box is the area controlled by the Webpack-dev-server code, and the red box is the file system. To understand how this works, let’s take a quick look at the related names:
Webpack-dev-server
: a server plug-in, equivalent to an Express server, that starts a Web server and is only suitable for development environmentsWebpack-dev-middleware
: webpack-dev-server middleware that listens for resource changes and then packages themWebpack-hot-middleware
: Middleware, which can achieve no refresh of the browser update
process
Next, let’s take a detailed look at the whole working principle of HMR:
1. Monitor code changes and recompile packages
In Webpack’s Watch mode, changes to a file in the file system are detected, and modules are recompiled and packaged according to the configuration file
2. Save the compilation result
Webpack-dev-middleware calls Webpack’s exposed API to monitor code changes and tells Webpack to store the packaged code in memory as a simple JavaScript object.
- Why not put the compiled results in the specified output directory?
Because code accessing memory is faster than accessing files in the file system, it can reduce the overhead of writing code
3. Listen for file changes and refresh the browser
Webpack-dev-server starts to monitor file changes, note that this is not a recompile package to monitor code changes. . When we are in the configuration file is configured with devServer watchContentBase to true, Webpack dev – server can monitor configuration static files in the folder change, change, notify the browser to refresh the browser to application of this and HMR are two concepts
4. Set up the WebSocket protocol to synchronize the compilation status
Establish a websocket long connection between the browser and the server through the dependency of SockJS of Webpack-dev-server, and then synchronize the status information of each phase of Webpack compilation and packaging to the browser. Also includes information from step 3 that webpack-dev-server listens for file changes.
—— Hash value of the new module (webpack-dev-server sends the hash value of the compiled new module to the browser using the socket via _sendStats method). In the next step, the browser will perform module hot replacement based on the hash value
5. The browser advertises messages
Since webpack-dev-server/client cannot request updated code and does not perform hot module operations, the work is handed back to Webpack.
6. Pass hash to HMR
HotModuleReplacement runtime is the centre of the client HMR, step on it receives hash value passed to it.
webpack-dev-server/client
callcheck
The webpack-dev-server/client method detects updates and determines whether to refresh the browser or hot update the module based on the information passed by webpack-dev-server/client and the configuration of dev-server. If the browser refreshes, there is no following step
7. Check whether updates exist
HotModuleReplacement. Runtime calls check () method, is called JsonpMainTemplate. The two methods in the runtime
HotDownloadUpdateChunk (to get the latest module code) and hotDownloadManifest (to get if there are updated files)
8. Request to update the file list
Call the hotDownloadManifest method to make an AJAX request to the server to see if there is an update file, and the server returns a JSON containing the hash values of all the modules to be updated
9. Request to update the latest module
Call the hotDownloadUpdateChunk method to get the latest module code via a JSONP request, using the updated list obtained in the previous step. And returns the code to the HMR Runtime, which determines whether it is a browser refresh or a module hot update
10. Update modules and dependencies
HotApply HMR Runtime hotApply removes expired modules and code and adds new modules and code to implement hot updates
11. Hot update error handling
During the update process, abort and FAIL errors may occur in the hotApply process, and the hot update is returned to the refresh browser so that the entire module is hot updated. This is the whole principle analysis of HMR.
conclusion
Let’s simplify and summarize the overall process
-
HMR is developed through Webpack with Webpack-dev-server, and maintains a long connection through webscoket so that the client and server can communicate
-
Server-side processing is mainly to listen for changes, mainly for the following points:
- Webpack is responsible for listening for file changes, repackaging, and saving the compiled results to memory
- Webpack-dev-server is responsible for notifying Webpack to save compilation results, listening for file changes, and notifying the browser to refresh
- The browser side mainly realizes the update according to the type, mainly including the following points:
-
Webpack-dev-server is responsible for setting up a long connection to synchronize status information (hash)
-
Webpack is responsible for receiving the hash message sent by the browser and determining the refresh type to determine whether the HMR process continues, and if so, forwarding the hash message to the HMR core
-
The HRM core center is responsible for request interaction with the server Webpack-dev-server through two methods, hotDownloadUpdateChunk (module code update) and hotDownloadManifest (file update), so as to obtain the resources needed for update operations. Hot update via hotApply. If an error occurs during this process, fall back to browser update.
The above is the principle of HMR analysis of all, if you want a more in-depth understanding of HMR, it is recommended to slowly read the source code