为什么需要hmr
- live reload 会使应用状态丢失。比如model需要重新点开
hmr兼容市面上大多数框架和库比如react-hot-loader,vue-loader等,能监听组件变化,将最新的组件更新到浏览器端。
webpack-dev-middleware 在 HMR 过程中扮演什么角色?
打包后的新模块又是通过什么方式发送到浏览器端的呢?
为什么新的模块不通过 websocket 随消息一起发送到浏览器端呢?
HMR 又是怎么将老的模块替换成新的模块,在替换的过程中怎样处理模块之间的依赖关系?
当模块的热替换过程中,如果替换模块失败,有什么回退机制吗?
manifest
当 compiler 开始执行、解析和映射应用程序时,它会保留所有模块的详细要点,这个数据集合称为 manifest。
过程
- webpack监听文件或模块,当文件或模块发生变化时,重新编译,并将打包。
- webpack-dev-middleware调用webpack暴露的API,告诉webpack将代码写入内存。
- webpack-dev-server通过sockjs和浏览器端建立长链接,并把webpack打包编译的各个阶段告诉浏览器。告诉浏览器有模块需要更新。浏览器根据收到的不同值进行不同的操作。更新阶段主要还是hash值,浏览器根据hash值进行去热更新。
- HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上一步传递给他的新模块的 hash 值,它通过 JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回一个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。
- HotModulePlugin 将会对新旧模块进行对比,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。
- 失败后会对浏览器进行reload live,来获取最新的打包代码。
