Hot Module Replacement(简称 HMR)
第一步:webpack 对文件系统进行 watch 并打包到内存中
webpack-dev-middleware
会调用 webpack 的 api 对文件系统进行 watch,当文件发生改变时,webpack 重新进行打包,然后存到内存中。(这里存到内存是因为访问内存中的代码比访问文件更快,可以减少 webpack 的开销)
第二步:devServer 通知浏览器端文件发生变化
在启动 devServer
时,sockjs
在服务端和浏览器端之间建立一个 websocket 连接,将 webpack 的编译和打包信息发送给浏览器端,这个阶段 webpack-dev-server
会调用 webpack 的 api 对 compiler 的 done
事件进行监听,当执行完 done 时马上将新编译包的 hash 值发送给浏览器端。
第三步:webpack-dev-server/client 接收服务端发送的信息并进行处理
webpack-dev-server/client 本身并不能向服务器端请求更新的代码,当服务器传送过来 type 为 hash 消息时便会将 hash 值暂存起来,如果 type 为 ok 消息则会进行 reload
操作,reload 会根据配置选择是进行刷新浏览器还是热更新。
第四步:接收到 hash 值后进行处理
HotModuleReplacement.runtime
接收到上一步发送的 hash 值之后,会调用 JsonpMainTemplate.runtime
向服务器先发送一个 ajax 请求是否有文件更新,如果有则返回更新列表的 hash 值,再发送一个 jsonp 请求,获取最新的模块代码。
第五步:对更新的模块代码进行校验并更新
HotModulePlugin
会对新旧模块进行对比,并检查模块之间的依赖关系,更新模块同时也更新依赖,如果更新失败就会退回到 reload 操作,刷新浏览器去获取更新的模块。