技术·MiniCordis:从零实现一个插件化 Runtime · 第 7 篇·2026-08-27·7 分钟

第六篇:把所有机制重新拼回一个完整场景

这一篇要解决的问题是:前面一路建立起来的这些机制,放在一起以后到底能不能支撑一个像 HelloCordis 那样的真实小场景。为了把这个问题讲清楚,我们不会再继续新增 API,而是直接回到 examples/hello-cordis/,看这些机制如何在同一个运行流程里彼此配合。

1. 这一篇要解决的问题

前面几篇分别解决了容器、能力表、Plugin 安装、可逆 effect、scope、Event、依赖生命周期、失败隔离和 Child Context。它们单独看都成立,但一套 Runtime 设计真正有说服力的时候,不是在每个局部机制都“说得通”,而是在它们被放进同一个有意义的场景里之后,仍然能够稳定配合。

所以这一篇要回答的,其实是整组教程最后的问题:

这些机制拼在一起,能不能形成一个真正闭合的 Runtime 模型?

这对应 mini-cordis 里的 v1.0。

这一篇的主线可以先压缩成下面这条路径:

text
把机制单独做对
   ↓
把机制放回同一场景
   ↓
观察它们是否真正协同
   ↓
验证 Runtime 模型是否闭合
HelloCordis 完整运行流程图
HelloCordis 完整运行流程图

2. 上一阶段卡在哪里

如果只有单元级测试,我们可以证明很多局部性质,比如某个 cleanup 会被执行、某个 listener 会被自动移除、某条依赖在满足时会被激活。但这些都还不足以证明:当 Plugin、Effect、Event 和响应式依赖一起出现时,系统仍然表现正确。

例如下面这些问题,只有回到完整场景里才会真正暴露:

text
App 在依赖不存在时会不会误激活?
Greeter 出现时,App 会不会自动启动?
Greeter 消失时,App 会不会自动停掉?
Logger 和 Analytics 会不会在不认识 Greeter 的情况下收到事件?
更换 Greeter 实现时,整个流程会不会自动重新接上?

如果这些问题都能被同一套机制自然回答,那么 MiniCordis 才算真正完成了它的第一阶段目标。

3. 这一篇引入什么机制

examples/hello-cordis/ 之所以是一个很好的最终场景,是因为它把前面几乎所有关键机制都重新召回来了。

Greeter 的安装与卸载,依赖的是:

text
Plugin
Effect
Scope

App 的激活与停用,依赖的是:

text
inject
Reactive Dependency Lifecycle

Logger 和 Analytics 的感知方式,依赖的是:

text
Event
Listener cleanup

而切换英文和中文 Greeter 的过程,则把“能力会消失、会恢复、依赖会重新激活”这条主线完整跑了一遍。

也就是说,这一篇并不发明新的局部机制,它引入的“机制”其实就是一次完整的集成验证:把前面所有抽象重新放回同一个运行场景里,观察它们是否能自然配合。

4. 代码里真正加了什么

完整流程的入口在配套仓库的 examples/hello-cordis/index.ts。

它先安装 Logger 和 Analytics,再安装会等待 greeter 的 App,随后安装英文 Greeter、卸载它、再安装中文 Greeter。这个顺序本身就是一个 Runtime 实验:App 并没有直接 import 任何 Greeter 实现,但它会随着 greeter 的存在与否自动激活或停用。

其中最能说明问题的是 examples/hello-cordis/app.ts 里的 App:它没有手写“如果没有 greeter 就先 return,未来再试一次”的流程,而是直接声明:

ts
ctx.inject(['greeter'], (ctx) => {
  // ...
})

这意味着依赖关系已经不再由 App 自己维护,而是交给 Runtime 了。Logger 也同样没有直接认识 Greeter,而只是在 examples/hello-cordis/logger.ts 里通过 ctx.on('greet', ...) 被动接收事件。于是整个系统形成了一种非常干净的关系:Greeter 负责提供能力,App 负责声明依赖,Logger 和 Analytics 负责监听事件,而这些模块之间的生命周期同步都由 Runtime 统一接住。

从输出结果看,这个流程通常会呈现为:

text
Context start
Logger + Analytics installed
App installed (waits for greeter)
EnglishGreeter installed
[App] Hello, Alex!
[LOG] greeted Alex
[ANALYTICS] Alex said hi
EnglishGreeter unloaded
[App] deactivated (greeter unavailable)
ChineseGreeter installed
[App] 你好,Alex!
[LOG] greeted Alex
[ANALYTICS] Alex said hi

这条输出之所以有说服力,不在于它有多炫,而在于它逐行证明了前面几篇建立的机制确实正在一起工作。

5. 这一篇的结论

这一篇最重要的结论是:MiniCordis 到 v1.0 的价值,不在于它已经变成了一个完整框架,而在于它用一套很小的代码,把“能力注册、安装撤销、事件解耦、依赖激活、局部隔离”这些 Runtime 问题真正闭合成了一条工作流。也正因为它的范围被控制得足够小,读者才有可能把这套模型完整看清楚。

到这里,这一组教程真正想建立的认识也就闭合了:MiniCordis 的重点从来不是复刻 Cordis 的所有功能,而是把一个插件化 Runtime 最核心的内部机制,从零实现一遍,并且让这套机制在一个完整场景里自洽地跑起来。

《MiniCordis:从零实现一个插件化 Runtime》合集 · 第 7 / 7 篇