意义
代码修改并保存后,webpack会代码重新打包,并将最新的模块发送到浏览器端,浏览器通过热的模块更新旧模块。这样在不刷新浏览器的前提下就能够对应用进行更新。
HMR的核心就是客户端从服务端拉取更新后的文件(chunk diff【chunk需要更新的部分】),当本地资源发生变化时,WDS(webpack-dev-server)会向浏览器推送更新,并带上构建时的hash,客户端与上一次资源进行对比。存在差异会向WDS发起ajax请求获取更改的内容。
HMR工作原理流程图
- 1: webpack在dev模式下,webpack会watch文件系统的文件修改,一旦监听到文件变化,webpack就会对相关模块进行重新打包,打包完后将代码保存在内存中。
- 2:webpack和webpack-dev-server之间的交互,主要是利用webpack-dev-server里的webpack-dev-middleware中间件调用webpack暴露给外部的API对代码变化进行监控。
- 3:webpack-dev-server对静态文件变化的监控,如果配置文件中静态文件发生变化,则会通知浏览器重新加载,即live reload(刷新)。
- 4:服务器端的webpack-dev-server利用sockjs在浏览器和服务器之间建立一个websocket长链接,将webpack打包变化信息告诉浏览器端的webpack-dev-server,打包生成不同hash值
- 5:浏览器端的webpack-dev-server接收到的信息有变化时,会通知webpack/hot/dev-server,这是webpack的功能模块,它会根据浏览器端的webpack-dev-server传递的信息以及dev-server的配置,决定浏览器时执行刷新操作还是热更新操作
- 6:刷新操作,则直接通知浏览器进行刷新。如果是热更新操作,会通知热加载模块hotModuleReplacement.runtime,这个是卢兰其端HMR的中枢系统,负责接收上一步传递过来的hash值,然后通知并等待下一个模块即JsonpMainTemplate.runtime向服务器发送请求的结果。
- 7:hotModuleReplacement.runtime通知JsonpMainTemplate.runtime模块要进行新的代码请求,并等待其返回的代码块。
- 8:JsonpMainTemplate.runtime先向服务端发送请求,请求包含hash值的json文件
- 9:获取到所有要更新模块的hash值之后,再次向服务端发送请求,通过jsonp的形式,获取到最新的代码块,并将此代码块发送给HotModulePlugin.
- 10: HotModulePlugin将会对新旧模块进行对比,决定是否需要更新,若需要更新,则会检查其依赖关系,更新模块的同时更新模块间的引用。
简单说明
- 第一步:webpack对文件系统进行watch打包到内存中
- 第二步:devServer通知浏览器端文件发生改变
- 第三步:webpack-dev-server/client接收到服务端消息做出响应
- 第四步:webpack接收到最新hash值验证并请求模块代码
- 第五步;HotModuleReplacement.runtime对模块进行热更新