Webpack 热更新(HMR)工作原理详解
Webpack 开发服务 与 浏览器建立持续通信通道,代码变化后只推送变更模块,浏览器局部替换,无需刷新整页。
一、什么是热更新
热更新(Hot Module Replacement,简称 HMR)可以理解为:Webpack 开发服务和浏览器之间建立了一条 持续通信的通道,代码变了以后,Webpack 把变化告诉浏览器,浏览器再 只替换变化的模块。
这样做的好处是:
修改代码后不用刷新整个页面,状态不丢失
只替换变更模块,更新速度快
开发体验更流畅,所见即所得
二、初始化连接流程
在这个项目中,页面加载时的连接建立流程如下:
浏览器打开页面
页面加载 entry.page1.js
webpack.dev.js 已将
webpack\-hot\-middleware/client加入入口客户端在浏览器中连接
/__webpack_hmr,建立长连接通道
关键点:webpack-hot-middleware/client 是运行在浏览器端的客户端代码,负责与服务端保持通信。
三、代码变更后的更新流程
当你修改 .vue / .js 文件时,热更新的完整链路如下:
| 步骤 | 发生了什么 |
|---|---|
| 1 | 修改 .vue / .js 文件 |
| 2 | devMiddleware 监听到文件变化 |
| 3 | Webpack 重新编译变化的模块(不是全部) |
| 4 | 编译结果暂时放在**内存中**(不写入磁盘) |
| 5 | hotMiddleware 通过 /__webpack_hmr 通知浏览器:有更新 |
| 6 | 浏览器收到消息后,请求最新模块 |
| 7 | Webpack 运行时替换旧模块,页面局部更新 |
举个例子
假设你只修改了模板中的一行:
{{ title }}Webpack 不会重新加载整个项目,而是重新编译这个组件对应的模块,然后浏览器只替换这部分内容。页面上其他组件的状态(比如表单输入、滚动位置)都能保留。
四、四个核心角色
热更新体系中有四个关键角色,各司其职:
| 角色 | 职责 |
|---|---|
| devMiddleware | 负责**监听文件变化**、触发重新编译、提供最新资源(内存文件系统) |
| hotMiddleware | 负责把「代码有更新」的消息**发送给浏览器**(推送通知) |
| webpack-hot-middleware/client | 运行在浏览器中,接收消息、请求新模块并应用更新 |
| HotModuleReplacementPlugin | 让 Webpack 本身**具备模块替换能力**(核心插件) |
五、兜底机制:自动刷新
reload: true — 热更新失败时的安全网
如果修改的模块无法被热替换(比如某些没有 HMR 接受处理的模块),或者更新过程中出现错误,配置中的 reload=true 会让浏览器自动刷新整个页面。
这样做的目的是:保证最终使用的一定是最新代码,不会因为热更新失败而停留在旧版本。
总结: devMiddleware 管编译,hotMiddleware 管通知,client 管浏览器端应用,HotModuleReplacementPlugin 提供底层能力。四者配合,实现「改代码 → 局部更新 → 不丢状态」的流畅开发体验。
