webpack 的热更新原理

Webpack 的热更新(HMR, Hot Module Replacement)原理核心在于:不刷新整个页面,只替换发生变化的模块,从而保持应用状态,提高开发效率。

HMR 工作流程

整个过程可以分为 5 个核心步骤:

1. 启动 Dev Server
  • 使用 webpack-dev-server 或 webpack-hot-middleware 启动服务。

  • Dev Server 使用 Express 启动本地服务器,默认端口 8080。

  • 内部集成 webpack-dev-middleware,用来把构建产物保存在 内存中(不是 dist 目录)。

2. 建立 WebSocket 连接
  • 浏览器端运行一个 HMR Client(通常注入到入口文件)。

  • HMR Client 通过 WebSocket 与 Dev Server 建立长连接。

  • 当源码变化时,Dev Server 会通过 WebSocket 向客户端 发送更新消息。

3. 文件变化 → 重新编译
  • 当源码文件修改时,webpack 监听到变化,触发 重新编译。

  • Webpack 使用 增量编译(只编译改动的模块及依赖)。

  • 生成 新的编译产物(chunk hash 变化)。

4. 生成更新补丁(Manifest + Chunk)
  • Webpack 会生成 manifest(清单文件),记录哪些模块变了。

  • 同时生成 更新模块的 JS 文件(称为 hot-update.js)。

  • Dev Server 通过 WebSocket 告诉客户端:哪些模块更新了,以及更新文件的 URL。

5. 客户端替换模块
  1. 浏览器端的 HMR Runtime 收到更新通知后:

    • 通过 JSONP 或 fetch 拉取 hot-update.js。

    • 使用 webpack_require.hot.accept() 钩子,替换对应模块的逻辑。

    • 不会刷新页面,只执行更新模块的代码。

  2. 如果更新失败(比如模块不支持 HMR),则会 回退到页面刷新。

关键技术点

  • WebSocket 通信:实现双向实时推送。

  • 增量编译:只重新打包修改部分,减少构建时间。

  • 模块热替换 API:module.hot.accept(),开发者可自定义更新逻辑。

  • 回退机制:不支持 HMR 的情况,执行 window.location.reload()。

流程图(简化)
源码改动 → webpack 重新编译 → 生成 hot-update.js
      ↓
Dev Server 通知客户端(WebSocket)
      ↓
客户端拉取补丁 → 替换模块 → 视图更新(状态保留)
HMR 和 Live Reload 区别
特性 HMR Live Reload
页面是否刷新 ❌ 否(只替换模块) ✅ 是(整页刷新)
状态是否保留 ✅ 保留(React 组件状态) ❌ 丢失
性能 高效(只更新部分代码) 低效(刷新整个页面)
posted @ 2025-09-01 16:59  煜火  阅读(26)  评论(0)    收藏  举报