Webpack HMR 模块热更新特性
简介
HMR(Hot Module Replacement) 是 webpack 中广受开发者欢迎的一个特性。
这个特性可以让开发调试前端应用的效率更高。
历史背景
刀耕火种
在没有前端工程化的年代,开发调试一个前端应用很简单,也很原始。
修改源码 --> 手动刷新页面 --> 还原现场
自动刷新
后来,有了 webpack 工程化,可以节省一步手动刷新页面的操作。
修改源码 --> 还原现场
缓解方案
刀耕火种和自动刷新的方案,都有其弊端,就是会导致应用调试期间的所有临时状态丢失。
要解决临时状态丢失,最直接的办法就是把临时状态编写在业务代码中,待正式调试完毕,再把这些业务无关的代码删除掉就 OK 了。
Webpack HMR 方案
基于以上的历史发展背景,有无一种更好的方式,既可以无需手动刷新页面,也可以保留调试期间的临时状态,还无需手动加一些业务无关的临时调试代码呢?
这听起来好像有点太美好了。但事实上还是有办法做到的,人类的一大特点就是会使用和制造各种工具。
把变化和不变的部分找出来,然后分开处理,自然就可以找到方法了。
方案类比
实际上,在网页技术发展的历程上,有一种场景遇到的问题以及其解决方法,都跟模块热更新很像。
在 web 发展的初期,网页能做的事情十分有限,不像今天的 web 前端应用一般百花齐放、复杂度节节攀升。
很久以前,网页上提交表单的过程都是
用户点击提交按钮 --> 等待服务器响应 --> 服务器根据提交返回最新的页面
返回的最新页面,其更新的地方,很可能只是其中一小部分,例如把页面显示提交状态的提示语从提交中变成提交成功。
自从 AJAX 出现以来,改变了这种局面。这种技术:
通过 JS 脚本发起请求 --> 请求服务器提供的接口 --> 返回 XML 数据 --> JS 脚本根据 XML 局部修改页面
方案设计
我们可以看到,不变的是流程:
修改源码 --> 触发页面局部更新
变化的是更新的方式:
对于 JavaScript 脚本,更新千变万化,需要定制。
对于 CSS 样式文件,向页面插入最新的样式规则即可。例如使用插入 style 标签的方式,覆盖上一次的样式。
工作原理
puml 流程图
启动本地开发服务器
开发服务器与 nodejs 进程保持通讯
IDE 中有源码更新
推送更新消息至开发服务器
开发服务器的一些脚本,根据传过来的更新数据,执行局部更新
假设热更新失败,则回退到实时刷新(live reloading)
如何配置
社区生态
社区生态中的一些库或者工具,一般已经内置了热更新规则。
css-loader 和 style-loader 在开发环境已经默认配置好
react、vue 等这样的框架,因为其编写组件、组织代码的方式有其规则和约束,把模块热更新规则内置在一些基于 webpack 的官方 CLI 工具中例如 create-react-app、vue-cli
redux、vuex 等状态管理工具也有其内置的热更新机制。
个人定制
如果是个人开发的库或一些工具,则需要基于 webpack HMR 的规则进行定制。
如何定制
在模块的末尾增加 module.hot 回调函数,指定模块热更新规则

浙公网安备 33010602011771号