模块热替换 HMR
基本概念
模块热更新 hot module replacement: 在应用程序运行过程中替换、添加 或 删除模块, 无需重新加载整个页面。
在应用程序中
(设置 HMR, 使进程自动触发更新, 或者可以选择在用户交互时进行更新)
- 应用程序代码要求 HMR runtime 检查更新
- HMR 异步下载更新, 通知 应用程序代码
- 应用程序代码要求 HMR runtime 应用更新
- HMR runtime 同步应用更新
在编译器中
compiler emit update, 允许从之前版本更新到新版本, update 由两部分组成
- 更新后的 manifest (JSON)
- 一个或多个更新后的 chunk (Javascript)
manifest 包括新的compilation hash 和 所有更新的 chunk list, 每个 chunk 包含了所有更新的模块, 或者是一个模块移除的标志。
compiler 确保 modules IDs 和 chunk IDs 在构建时保持一致, 这些 ID 通常保存在内存中, e.g.webpack-dev-server
,也有可能存储在 JSON file 中
在 HMR Runtime 中
对于模块系统的 runtime, 附加的代码被发送到 parents 和 children 跟踪模块。在管理方面,runtime 支持两个方法, check 和 apply
- check 发送 HTTP 请求来更新 manifest, 如果请求失败, 表示没有可用更新。如果请求成功, 待更新chunk 和当前加载过的 chunk 进行比较。 对每个加载过的 chunk,会下载相对应的待更新 chunk。当所有待更新 chunk 完成下载, 会准备切换到 ready 状态。
- apply 方法将所有被更新模块标记为无效。对于每个无效模块, 都需要在模块中有一个更新处理函数 update handler, 或者在它的父级模块中有个更新处理函数。否则, 无效标记冒泡, 并也使父级无效。每个冒泡继续, 直到到达应用程序入口起点,或者到达带有更新函数的模块, 以最先到达为准, 冒泡停止。如果他从入口起点开始冒泡, 此过程失败。
- 之后所有无效模块都被 dispose 处理函数处理和解除加载。然后更新当前 hash,并且调用所有 accept 处理函数,runtime 切换回 idle state。
模块热更新指南
https://www.webpackjs.com/guides/hot-module-replacement/
API
如果已经通过 HotModuleReplacementPlugin
启用了模块热更新,则它的接口将会暴露在module.hot
属性下面。通常用户先检查这个接口是否可访问,然后再使用。
api | 用法 |
---|---|
accept | 接收给定依赖模块的更新,并触发一个回调函数来对这些更新做出响应 |
decline | 拒绝给定依赖模块的更新 |
dispose | 添加一个处理函数,当前模块代码被替换时执行 |
removeDisposeHandler | 删除由 dispose 或 addDisposeHandler 添加的回调函数 |
status | 取得模块热替换进程的当前状态 |
check | 测试所有加载的模块以进行更新,如果有更新,则应用他们 |
apply | 继续更新进程 |
addStatusHandler | 注册一个函数监听status 的变化 |
removeStatusHandler | 移除一个注册的状态处理函数 |
网友评论