🐳 第五章 Cordis让插件能够动态组合
📄 一句话概括

实测配置里有两件 HMR 包(宿主侧 dsh-hmr、界面侧 dsh-client-hmr);HMR 敢【不重启换插件】,靠的正是前几节那套生命周期兜底。

📝 本节和前面几节的关系

前五节把生命周期讲透了,这一节看它的第一个红利:热替换。

一、HMR 是什么

HMR(热模块替换)= 改了插件不重启:卸下旧的、挂上新的,系统继续跑。

对开发体验的意义不用多说:改一行代码,不用重来整个会话。

但对运行系统的意义更重:长会话不用中断——Agent 正干着活,插件升级了,换上就是。

二、实测:两件 HMR 包

两侧各一件——和 5.9 要讲的双 runner 一样,宿主平面与会话平面的变化各自处理。

顺带呼应 1.1:同一套 Runtime 长出四种产品形态,界面那侧的热更新就归各产品的客户端层管。

三、HMR 凭什么敢

把前几节的内容串起来,就是答案:

没有这套机制,HMR 就是边开车边换轮子——不是做不到,是出事没人知道坏在哪。

四、热替换的边界

HMR 不是无条件的:

能热替换的是【实现】,不是【契约】——这句话也解释了为什么接口稳定(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 秒实验

  1. 在配置树里确认两件 HMR 包的位置(顶层哪一段)。
  2. 列出三种【不能直接热替换】的情况。
  3. 想想长会话场景:插件升级时热替换替你省了什么?

常见误区

  1. 错误:HMR 是开发工具的专属功能,运行时无关。——纠正:运行时的热替换更值钱——长会话不用中断。
  2. 错误:热替换就是重新加载文件。——纠正:要先干净卸旧(账本+Effect),再走完整上岗三步。
  3. 错误:任何改动都能热替换。——纠正:能换的是实现不是契约;声明变了要重新评估影响面。
自测三问(点开对答案) 1. 实测的 HMR 包有哪两件? —— 宿主侧 `dsh-hmr`、界面侧 `dsh-client-hmr`——两条独立通道。 2. HMR 凭什么敢不重启换插件? —— **卸旧有账本、挂新走三步、出问题处境明确**——生命周期全套兜底。 3. 热替换的边界是什么? —— **能换实现不能换契约**——Effect 变了要重新评估,状态带不过去要等或迁移。

相关笔记