Webpack 的 HMR(热模块替换)热更新原理
请解释 Webpack 的 HMR(Hot Module Replacement)热更新机制的原理,包括 WebSocket 通信、增量更新、accept 回调的工作流程。
回答
Yahuda
HMR 完整流程:
文件修改 → Webpack 增量编译 → 发送 hash
→ WebSocket 通知 → 浏览器请求 JSON manifest + 更新 chunk
→ 运行时执行 accept 回调 → 模块热替换
详细步骤:
1. 启动阶段:
- Webpack Dev Server 启动,创建 WebSocket 连接
- 客户端注入
webpack/hot/dev-server.js和webpack-dev-server/client
2. 文件变化:
- Webpack 增量编译(仅重新编译变更模块及其依赖)
- 生成两个文件:
- JSON Manifest(
[hash].hot-update.json):描述哪些 chunk 更新了 - JS Update(
[hash].hot-update.js):包含更新的模块代码
- JSON Manifest(
3. 通知客户端:
- 通过 WebSocket 推送
{"type":"hash","data":"newHash"}和{"type":"ok"}
4. 请求更新:
- 客户端用 JSONP 方式请求更新的 JSON Manifest 和 JS Update
webpackHotUpdate回调注册新模块
5. 模块替换:
if (module.hot) {
module.hot.accept('./module.js', () => {
// 模块更新后的回调
const newModule = require('./module.js');
render(newModule);
});
}
- 运行时删除旧模块缓存,执行新模块
- 自动向上冒泡未处理 accept 的模块(导致页面刷新)
React Fast Refresh:基于 HMR 但更智能,保留组件状态。