← 返回目录

第 4 卷

第 4 / 6 卷日期:

看 b-chat 这行实测输出:

复制代码 1[chat] 收到:[b-provider/b-model] 回复:你好(我看到 shell 配置:{"model":"intercept-m

chat() 返回的还是 [b-provider/b-model],实例纹丝未动;但解析配置时,model 被 intercept 的值合并覆盖,provider 等没提到的字段原样保留。租户 B 两个都用:

isolate 给它私有 shell,intercept 让它看到被改写的 model。

图 10-1
图 10-1

到这里,cordis.yml 里绝大部分字段你都见过了。给你一份“字典”,忘了随时回来查:

id条目的稳定标识,组内子条目的全名会带祖先前缀tenant-a、tenant-a:a

./plugins/logger.ts、@ name插件模块:相对路径或包名 plugin-group

config传给插件的配置对象(先过 schema 安检)logger 的 level、shell

标记这是一个“组”条目,config 里是子条目数组;必须同时写 name: '@deepseek-ai/cordis-plugin-

group: truetenant-a / tenant-b group'——“组”不是语法糖,它本身就是一个真实插

件

disabled保留条目不挂载(祖先连坐)spare

给同名服务换 symbol 键,各住一间:字符串 = 标同 isolateshell: tenant-a、shell:

一 label 的共享一份,true = 条目私有

表外其实还有一个 inject 字段:它可在条目级追加插件依赖的服务(插件代码里 export const inject 的配置版),没就绪就停在 PENDING。这一讲的最终版配置没用到它,所

以没列进表里——用法与第二讲的代码版一致。

热更新(HMR)

先会用:HMR 怎么配、怎么跑

树搭好了,配置也讲完了。开发或线上部署时最烦的就是改一行配置 / 代码,重启整个进程。

HMR(Hot Module Replacement)就是干这个的:文件一变,只有相关的那块被替换,进程不重启。

hmr 插件要求进程带 --expose-internals 启动,所以我们构建了单独的一份 cordishmr.yml,业务部分用嵌套 include 复用 cordis.yml——一行内容都不用重复:

3name:'@deepseek-ai/cordis-plugin-timer'*
4-id: hmr #②HMR插件自己
5name:'@deepseek-ai/cordis-plugin-hmr'*
6config:
7root: # 监听哪些目录(省略也行,默认就是['
8-'.'
9-id: app #③嵌套include:直接复用cordis.yml
10name:'@deepseek-ai/cordis-plugin-include' # 业务配置一行都不用重复
11config:
12path:'./cordis.yml'

注意最上面那个 timer:它不是可选的装饰,而是必须挂的——HMR 要用 timer 服务做防抖,少了它 HMR 就会一直卡在 PENDING,而且一声不响:树照挂、其他插件照跑,只是热

更新永远不来。

于是入口和 main.ts 结构一致,还是建根、挂 Loader、挂 include 那三步,只有两处不同:config.path 换成 './cordis-hmr.yml',末尾加一行 setInterval(() =>

{}, 1000) 保活(HMR 要盯着文件,进程退出就没人监视了)。

启动命令如下(它连 Node 版本一起钉住了):

复制代码 1npx node@24 --expose-internals --import tsx src/ch04/hmr-main.ts

为什么强调 Node 版本?因为 HMR 要动 Node 内部的模块加载 API,各版本签名不同,版本不对会报错。第一次跑直接用上面这条命令就行。

启动后树照常挂载,然后就可以动手了。我们改两处试试:

  1. 改配置:把 cordis.yml 里 logger 的 level 从 !!js process.env.LOG_LEVEL ??
全站分卷索引 · 6 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷