webpack 模块热替换 (HMR - hot module replacement)

webpack 模块热替换 (HMR - hot module replacement)
最新回答
达阳云

2026-08-04 18:45:13

模块热替换 (HMR) 功能显著加速了开发速度,允许在应用程序运行时替换、添加或删除模块,无需重新加载整个页面。通过以下步骤,可以实现模块的置换:

设置 HMR 以自动触发更新或在用户交互时更新。

构建 bundle 时,加入 HMR runtime 和服务沟通的 js,如 module.hot.accept('./index.js', function() {})。文件修改后,webpack 重新构建,服务器通过 websocket 长连接向浏览器发送更新消息,浏览器通过 jsonp 拉取更新的模块文件并触发模块热替换逻辑。

HMR 在 compiler 中运行时,发出 "update" 包括新的 compilation hash 和所有 updated chunk 列表。通常将这些 ID 存储在内存中或 JSON 文件中,确保模块 ID 和 chunk ID 一致。

在模块中,HMR 是可选功能,影响包含 HMR 代码的模块。例如,使用 style-loader 追加补丁,实现 HMR 接口,当接收到更新时替换旧样式。

在 runtime 中,额外代码跟踪模块 parents 和 children 关系,check 方法发送 HTTP 请求更新 manifest,apply 方法标记无效模块并触发 update handler,直至应用程序入口起点或带有 update handler 的模块。

在运用 HMR 的例子中,设置 devServer.hot 为 true,并在 package.json 添加 script "start": "webpack-dev-server --hot --open"。更改 somethings.js 内容后,页面中的文本随即更新。

webpack 的 watch 模式下,webpack 在内存中打包文件系统,减少代码写入文件的开销。devServer 与浏览器建立 webSocket 长连接,告知浏览器编译状态,完成模块热更新。

在浏览器接收到服务端消息后,通过 webpack-dev-client 的代码,执行 reload 操作或进行热更新。根据配置,调用 webpack/hot/emitter 获取最新 hash 值,发送给 webpack 客户端代码进行更新。

业务代码写法中,当模块更新后,需要在业务代码中调用 HMR 的 accept 方法添加模块更新后的处理函数,以确保页面能及时显示最新内容。

综上,HMR 提供了无缝的开发体验,显著提升了开发效率,简化了模块更新流程。