We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HMR 全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用
HMR
Hot Module Replacement
例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失
如果使用的是 HMR,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用
在webpack中配置开启热模块也非常的简单,如下代码:
webpack
const webpack = require('webpack') module.exports = { // ... devServer: { // 开启 HMR 特性 hot: true // hotOnly: true } }
通过上述这种配置,如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中
css
但是,当我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热模块
js
所以,HMR 并不像 Webpack 的其他特性一样可以开箱即用,需要有一些额外的操作
Webpack
我们需要去指定哪些模块发生更新时进行HRM,如下代码:
HRM
if(module.hot){ module.hot.accept('./util.js',()=>{ console.log("util.js更新了") }) }
首先来看看一张图,如下:
上面图中,可以分成两个阶段:
在编写未经过webpack打包的源代码后,Webpack Compile 将源代码和 HMR Runtime 一起编译成 bundle 文件,传输给 Bundle Server 静态资源服务器
Webpack Compile
HMR Runtime
bundle
Bundle Server
当某一个文件或者模块发生变化时,webpack 监听到文件变化对文件重新编译打包,编译生成唯一的hash值,这个hash 值用来作为下一次热更新的标识
hash
根据变化的内容生成两个补丁文件:manifest(包含了 hash 和 chundId ,用来说明变化的内容)和 chunk.js 模块
manifest
chundId
chunk.js
由于socket服务器在HMR Runtime 和 HMR Server之间建立 websocket链接,当文件发生改动的时候,服务端会向浏览器推送一条消息,消息包含文件改动后生成的hash值,如下图的h属性,作为下一次热更细的标识
socket
HMR Server
websocket
h
在浏览器接受到这条消息之前,浏览器已经在上一次 socket 消息中已经记住了此时的 hash 标识,这时候我们会创建一个 ajax 去服务端请求获取到变化内容的 manifest 文件
ajax
mainfest文件包含重新build生成的hash值,以及变化的模块,对应上图的c属性
mainfest
build
c
浏览器根据 manifest 文件获取模块变化的内容,从而触发render流程,实现局部模块更新
render
关于webpack热模块更新的总结如下:
webpack-dev-server
The text was updated successfully, but these errors were encountered:
总结中的 ”通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)“ 与正文的 “浏览器已经在上一次 socket 消息中已经记住了此时的 hash 标识,这时候我们会创建一个 ajax 去服务端请求获取到变化内容的 manifest 文件” 是否矛盾?问了同义千问,答复赞同了总结中的 “服务器主动发送” ,有没有大佬给个确切答复
Sorry, something went wrong.
No branches or pull requests
一、是什么
HMR
全称Hot Module Replacement
,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失
如果使用的是
HMR
,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用在
webpack
中配置开启热模块也非常的简单,如下代码:通过上述这种配置,如果我们修改并保存
css
文件,确实能够以不刷新的形式更新到页面中但是,当我们修改并保存
js
文件之后,页面依旧自动刷新了,这里并没有触发热模块所以,
HMR
并不像Webpack
的其他特性一样可以开箱即用,需要有一些额外的操作我们需要去指定哪些模块发生更新时进行
HRM
,如下代码:二、实现原理
首先来看看一张图,如下:
上面图中,可以分成两个阶段:
在编写未经过
webpack
打包的源代码后,Webpack Compile
将源代码和HMR Runtime
一起编译成bundle
文件,传输给Bundle Server
静态资源服务器当某一个文件或者模块发生变化时,
webpack
监听到文件变化对文件重新编译打包,编译生成唯一的hash
值,这个hash
值用来作为下一次热更新的标识根据变化的内容生成两个补丁文件:
manifest
(包含了hash
和chundId
,用来说明变化的内容)和chunk.js
模块由于
socket
服务器在HMR Runtime
和HMR Server
之间建立websocket
链接,当文件发生改动的时候,服务端会向浏览器推送一条消息,消息包含文件改动后生成的hash
值,如下图的h
属性,作为下一次热更细的标识在浏览器接受到这条消息之前,浏览器已经在上一次
socket
消息中已经记住了此时的hash
标识,这时候我们会创建一个ajax
去服务端请求获取到变化内容的manifest
文件mainfest
文件包含重新build
生成的hash
值,以及变化的模块,对应上图的c
属性浏览器根据
manifest
文件获取模块变化的内容,从而触发render
流程,实现局部模块更新三、总结
关于
webpack
热模块更新的总结如下:webpack-dev-server
创建两个服务器:提供静态资源的服务(express)和Socket服务参考文献
The text was updated successfully, but these errors were encountered: