跳到主内容

热更新HMR(Hot Module Replacement)的原理解读

· 3分钟阅读

Hot Module Replacement(简称 HMR)模块热更新,现代构建工具和开发必备的特性,能够监听文件修改,把改动的代码重新打包后发送到浏览器,在不刷新浏览器的情况下替换变更部分内容。比如修改 CSS 代码,浏览器不需要刷新就可以看到新的样式效果。现在很多构建工作,比如 webpack,vite 等都实现了热更新,那么是如何实现的呢?下面针对 webpack 的热更新原理进行探讨

热更新原理

下面针对不同的角度上描述热更新的原理,在了解原理之前,先看下了解几个核心概念

HMR Runtime:webpack 会构建时候生成一段 HMR Runtime 的 js 代码连同 bundle.js 发送到客户端运行,主要是用来接收模块更新

HMR Server:当有新的更新生成时,HMR Server 会发送一段 json HMR Runtime

manifest:用来管理模块之间交互的数据,存储模块的详细信息,可以分析模块到输出 bundle 之间的映射。当构建完成发送到浏览器,runtime 通过 manifest 解析和加载模块,所有的 importrequire 语句都会转换为 __webpack_require__ 方法,此方法指向模块标识符(module identifier)。通过使用 manifest 中的数据,runtime 将能够检索这些标识符,找出每个标识符背后对应的模块。

HMR流程

如何在应用层实现热更新

通过 HotModuleReplacementPlugin 启用了 Hot Module Replacement, 则该插件的接口将被暴露在 module.hot 以及 import.meta.webpackHot 属性下。请注意,只有 import.meta.webpackHot 可以在 strict ESM 中使用。

通常,用户先要检查这个接口是否可访问, 再使用它。你可以这样使用 accept 操作一个更新的模块:

if (module.hot) {
module.hot.accept("./library.js", function () {
// 获取到新的js代码后处理
});
}

// or
if (import.meta.webpackHot) {
import.meta.webpackHot.accept("./library.js", function () {
// 获取到新的js代码后处理
});
}

更多的 HMR 接口可以点击此链接查看