HMR通过构建工具监听文件变化并推送更新,实现模块热替换。1. 启动时建立websocket连接;2. 监听文件变更触发增量构建;3. 推送补丁包至浏览器;4. 客户端调用module.hot.accept处理更新;5. react用react-refresh、vue由vue-loader支持、vite通过import.meta.hot实现高效HMR。

热模块替换(Hot Module Replacement,简称 HMR)是现代前端开发中提升效率的重要机制。它允许在应用运行时,只替换修改过的模块,无需刷新整个页面,从而保留当前的页面状态,比如表单输入、ui 位置等。javaScript 的 HMR 主要依赖构建工具实现,如 webpack、Vite 等。
工作原理
HMR 的核心在于监听文件变化,并通过一个“通信通道”将更新推送到浏览器。当某个模块被修改后,构建工具会重新编译该模块,并生成一个“补丁包”,浏览器接收到后,决定是否接受更新并执行替换逻辑。
关键流程包括:
- 启动阶段:构建工具开启 WebSocket 服务,与客户端建立连接
- 监听变更:文件系统监听器检测到文件修改,触发增量构建
- 推送更新:构建完成后,通过 WebSocket 发送更新通知和新模块代码
- 模块替换:客户端根据 HMR 接口判断能否接受更新,执行替换并触发回调
模块接口与 accept 机制
不是所有模块都能被热替换,开发者需要显式声明哪些模块支持 HMR。以 Webpack 为例,可通过 module.hot.accept API 注册处理函数。
立即学习“Java免费学习笔记(深入)”;
例如:
module.hot.accept(‘./Button’, function() {
console.log(‘Button 模块已更新’);
// 可在此处重新渲染组件或更新实例
});
如果模块不接受更新,HMR 请求会向上冒泡,直到被处理或最终触发整页刷新。
框架中的实际应用
在 React 中,通常配合 react-refresh 或 @prefresh/webpack 实现组件热更新。这些插件会在编译时注入运行时代码,捕获组件定义并注册到 HMR 系统。
Vue 单文件组件则由 vue-loader 自动处理,style 和 template 修改可即时生效,script 部分也能保持状态。
Vite 利用原生 ES Modules 和浏览器 ESM 支持,通过 import.meta.hot 提供更轻量的 HMR 接口,更新速度更快,无需打包整个依赖图。
基本上就这些。HMR 虽然透明运行,但理解其机制有助于排查更新失败或状态丢失问题。关键是确保模块正确暴露 accept 回调,并合理管理副作用和状态生命周期。


