CodeWalk

Webpack HMR热更新原理(Hot Module Replacement)

作者:我还是少年 · 2026-05-30 12:55

详细解释Webpack HMR(热模块替换)的工作原理,包括Webpack Dev Server、WebSocket通信、模块哈希对比、以及React/Vue中的HMR实现机制。为什么HMR比Live Reload更高效?

回答

我还是少年

HMR核心流程

1. 监听文件变化

  • Webpack Dev Server使用chokidar监听文件系统变化
  • 检测到文件变更时通知Webpack重新编译

2. 增量编译与Hash

  • Webpack增量编译变更模块及其依赖
  • 生成:[hash].hot-update.json(更新清单)+ [chunk].hot-update.js(更新代码)
  • 每个模块编译后生成唯一hash,对比前后hash确定变化

3. WebSocket推送

  • WDS通过WebSocket发送更新信息(hash、chunk名)到浏览器
  • 浏览器Runtime收到消息后开始更新流程

4. JSONP请求更新

  • Runtime构建script标签,请求[chunk].[hash].hot-update.js
  • 新的模块代码会执行module.hot.accept()module.hot.dispose()

5. 模块替换

HotModuleReplacement.runtime
  → 检查模块的accept handlers
  → 执行旧模块的dispose清理
  → 替换模块缓存
  → 执行新模块代码
  → 标记为过期/

6. 冒泡机制

  • 若当前模块未定义accept,向上冒泡到父模块
  • 一直冒泡到entry仍未accept → 触发全量刷新(fallback到Live Reload)

React HMR实现

if (module.hot) {
  module.hot.accept('./App', () => {
    render(<App />, root);  // 重新渲染但保留状态
  });
}

Vue HMR实现

  • Vue Loader内置HMR支持
  • .vue文件通过module.hot.accept替换组件渲染函数
  • 保留组件实例状态(data/computed/watch)

HMR vs Live Reload

特性HMRLive Reload
页面变化不刷新页面全量刷新
状态保留✅ 保留组件状态❌ 所有状态丢失
更新速度毫秒级秒级(重载+重编译)
开发体验极佳一般

HMR的核心价值在于保持应用状态的同时更新代码,极大提升开发效率。