📄 一句话概括
实测配置里有两件 HMR 包(宿主侧 dsh-hmr、界面侧 dsh-client-hmr);HMR 敢【不重启换插件】,靠的正是前几节那套生命周期兜底。
📝 本节和前面几节的关系
前五节把生命周期讲透了,这一节看它的第一个红利:热替换。
一、HMR 是什么
HMR(热模块替换)= 改了插件不重启:卸下旧的、挂上新的,系统继续跑。
对开发体验的意义不用多说:改一行代码,不用重来整个会话。
但对运行系统的意义更重:长会话不用中断——Agent 正干着活,插件升级了,换上就是。
二、实测:两件 HMR 包
dsh-hmr——宿主侧:Runtime 的插件热替换。dsh-client-hmr——界面侧:前端资源的热更新。
两侧各一件——和 5.9 要讲的双 runner 一样,宿主平面与会话平面的变化各自处理。
顺带呼应 1.1:同一套 Runtime 长出四种产品形态,界面那侧的热更新就归各产品的客户端层管。
三、HMR 凭什么敢
把前几节的内容串起来,就是答案:
- 卸旧的:Fiber 账本在,逆序发起清理,Effect 逐项恢复。
- 挂新的:上岗三步照走,依赖齐了、条件给了才上岗。
- 出问题:处境明确(5.3)——坏了立刻知道坏在哪一步。
没有这套机制,HMR 就是边开车边换轮子——不是做不到,是出事没人知道坏在哪。
四、热替换的边界
HMR 不是无条件的:
- 声明变了(Effect 改了)——得重新评估影响面。
- 有会话正在用它——得等会话结束或走迁移。
- 状态没法迁移——旧实例的数据带不过去。
能热替换的是【实现】,不是【契约】——这句话也解释了为什么接口稳定(1.4)那么重要。
五、动手 Demo:Cordis 的 HMR 建立在生命周期之上
两件 HMR 包,加一张【凭什么敢】的清单:
hmrs = [("dsh-hmr", "宿主侧: Runtime 插件热替换"),
("dsh-client-hmr", "界面侧: 前端资源热更新")]
for a, b in hmrs:
print(" %-16s %s" % (a, b))
print()
print(" 凭什么敢:")
print(" 卸旧的 -> Fiber 账本 + Effect 恢复")
print(" 挂新的 -> 上岗三步照走")
print(" 出问题 -> 处境明确, 坏哪一步立刻知道")
实跑输出:
--------------------------------------------------------------------
Cordis 的 HMR 建立在生命周期之上
--------------------------------------------------------------------
实测:配置里有两件 HMR 相关的包:
包 在哪一侧
----------------------------------------------
dsh-hmr 宿主侧(Runtime 的热替换)
dsh-client-hmr 界面侧(前端的热更新)
----------------------------------------------
HMR(热模块替换)= 改了插件**不重启**:卸下旧的、挂上新的。
它凭什么敢这么干?因为生命周期机制兜着:
卸旧的 Fiber 账本在,逆序清理照做,现场恢复干净
挂新的 Effect 声明在,边界清楚,影响范围可预期
反过来想:如果没有 5.1~5.7 那一套,HMR 就是【边开车边换轮子】——
不是做不到,是出了事没人知道坏在哪一步。
两侧各一件——宿主与界面的热替换是两条独立通道。 HMR 是生命周期的红利:前几节越扎实,这一节越理所当然。 能热替换的是实现不是契约——接口稳定是热替换的前提。
30 秒实验
- 在配置树里确认两件 HMR 包的位置(顶层哪一段)。
- 列出三种【不能直接热替换】的情况。
- 想想长会话场景:插件升级时热替换替你省了什么?
常见误区
- 错误:HMR 是开发工具的专属功能,运行时无关。——纠正:运行时的热替换更值钱——长会话不用中断。
- 错误:热替换就是重新加载文件。——纠正:要先干净卸旧(账本+Effect),再走完整上岗三步。
- 错误:任何改动都能热替换。——纠正:能换的是实现不是契约;声明变了要重新评估影响面。
自测三问(点开对答案)
1. 实测的 HMR 包有哪两件? —— 宿主侧 `dsh-hmr`、界面侧 `dsh-client-hmr`——两条独立通道。 2. HMR 凭什么敢不重启换插件? —— **卸旧有账本、挂新走三步、出问题处境明确**——生命周期全套兜底。 3. 热替换的边界是什么? —— **能换实现不能换契约**——Effect 变了要重新评估,状态带不过去要等或迁移。- ☐ 下一节(5.7 Effect 与 Coeffect:插件增加什么,又需要什么)
相关笔记
- 逆序清理不等于逆序完成 —— 卸旧的核心动作
- 确保可用性 —— 不中断服务是可用性的老命题
- 先把【产品】和【Runtime】区分开 —— 界面侧热更新归客户端层管
- 🐳 DeepSeek Harness · 索引