Webpack HMR(热更新)解析

337 阅读3分钟

意义

代码修改并保存后,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对模块进行热更新