HMR 边界计算算法
热模块替换(HMR)边界决定更新传播范围,避免整页刷新。
HMR 边界概念
HMR 边界是一个模块:
- 接受自身及子模块的更新
- 不需要刷新页面即可更新
- 通常是组件或页面入口
边界计算流程
JavaScript
1. 文件修改触发 HMR
2. 查找对应模块
3. 向上遍历 importers
4. 找到第一个 accept 边界
5. 更新边界内所有模块
accept 边界标记
JavaScript
// Vue 组件自动 accept
import.meta.hot.accept((newModule) => {
// 组件接受热更新
})
// 或显式声明
if (import.meta.hot) {
import.meta.hot.accept()
}
注意:Vue 插件自动为组件添加 accept,无需手动声明。
边界计算示例
JavaScript
修改 components/Button.vue
Button.vue → importers: [App.vue]
App.vue → importers: [main.js]
main.js → importers: [] (入口)
App.vue 有 accept → App.vue 是边界
更新 App.vue 和 Button.vue
无边界情况
text
修改 utils.js
utils.js → importers: [main.js]
main.js 无 accept → 无边界
→ 触发完整页面刷新
propagateUpdate 算法
text
function propagateUpdate(module) {
// 模块有 accept
if (module.isHmrBoundary) {
return [module] // 返回边界模块
}
// 向上传播
const boundaries = []
for (const importer of module.importers) {
const result = propagateUpdate(importer)
boundaries.push(...result)
}
return boundaries
}
HMR 更新类型
| 类型 | 触发条件 | |
|---|---|---|
| 局部更新 | 找到 accept 边界 | |
| 页面刷新 | 无边界或边界失效 | |
| 完全重启 | 配置文件变化 |
自定义 HMR 边界
text
// 自定义模块接受热更新
export const data = { count: 0 }
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
// 保持数据状态
data.count = newModule.data.count
})
}
要点总结
- HMR 边界接受子模块更新
- 边界计算向上遍历 importers
- Vue 组件自动成为边界
- 无边界触发页面刷新
📝 发现内容有误?点击此处直接编辑