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 回调函数,指定模块热更新规则

posted @ 2022-04-10 17:06  葫芦瓜  阅读(19)  评论(0)    收藏  举报