5月27日 01:10

webpack 的热更新原理是什么?详细聊聊热更新的流程

HMR(Hot Module Replacement)的核心流程:

  1. webpack-dev-server 启动 WebSocket 服务,和浏览器建立长连接
  2. 文件变化 → webpack 重新编译 → 生成两个文件:[hash].hot-update.json(变更模块清单)和 [hash].hot-update.js(变更模块代码)
  3. 通过 WebSocket 推送 hash 事件给浏览器
  4. 浏览器用 AJAX 拉 hot-update.json,用 JSONP 拉 hot-update.js
  5. HMR runtime 找到变更的模块,执行 module.hot.accept 注册的回调
  6. 如果模块没有注册 accept,HMR runtime 向上冒泡,直到找到 accept 或刷新整个页面

Vue-loader、style-loader 等 loader 内部自动调用了 module.hot.accept,所以改 .vue 文件能无刷新更新。

追问

为什么需要两步拉取(json + js)?

hot-update.json 先确认哪些模块变了,如果当前页面没有引用变更模块,就不需要拉 hot-update.js。另外 json 由 webpack-dev-server 直接提供(内存文件系统),js 则走 JSONP 来避免跨域问题。

React Fast Refresh 和普通 HMR 有什么区别?

React Fast Refresh 在 HMR 基础上做了 React 组件的"签名"匹配——换掉的组件如果有相同的 hooks 调用和组件的导出签名,就保留下面的组件状态(state 不丢失)。普通 HMR 只是替换模块代码,状态会重置。

HMR 失效了怎么排查?

  • module.hot.accept 是否注册(检查对应 loader 是否配置正确)
  • 文件路径大小写不一致(macOS 不敏感但 webpack 敏感)
  • 配置文件中 hot: trueHotModuleReplacementPlugin 是否启用
标签:Webpack