02 工作区编排


文档摘要

02 工作区编排 本节摘要:OpenCode 是个有几十个包的大型单体仓库(monorepo)。这么多包怎么管?靠工作区(workspace)+ 任务编排。本节讲清这套编排:包之间怎么互相引用(工作区协议)、构建任务怎么增量(改一个包只重建受影响的)、为什么这种编排适合大型 monorepo。 一、几十个包的挑战 OpenCode 的源码不是一个包,而是几十个(模式层、协议层、服务端、领域核心、LLM、应用层、TUI、客户端、SDK、插件包......)。这带来几个挑战: 依赖管理:包 A 依赖包 B,怎么声明、怎么解析? 构建顺序:B 依赖 A,构建时得先建 A 再建 B。 增量构建:我改了 A,只重建 A 和依赖它的 B,不该全量重建。

02 工作区编排

本节摘要:OpenCode 是个有几十个包的大型单体仓库(monorepo)。这么多包怎么管?靠工作区(workspace)+ 任务编排。本节讲清这套编排:包之间怎么互相引用(工作区协议)、构建任务怎么增量(改一个包只重建受影响的)、为什么这种编排适合大型 monorepo。

一、几十个包的挑战

OpenCode 的源码不是一个包,而是几十个(模式层、协议层、服务端、领域核心、LLM、应用层、TUI、客户端、SDK、插件包......)。这带来几个挑战:

  • 依赖管理:包 A 依赖包 B,怎么声明、怎么解析?
  • 构建顺序:B 依赖 A,构建时得先建 A 再建 B。
  • 增量构建:我改了 A,只重建 A 和依赖它的 B,不该全量重建。
  • 版本一致:多个包用同一依赖(如 React),版本得统一。

这些挑战靠「工作区 + 任务编排」解决。

二、工作区:包间引用

工作区是包管理器(Bun workspaces)的功能,让同一仓库里的包能互相引用,不用发布到 npm 再安装:

monorepo 根 ├─ packages/ │ ├─ schema/ (包 @opencode/schema) │ ├─ protocol/ (包 @opencode/protocol,依赖 @opencode/schema) │ ├─ core/ (包 @opencode/core,依赖 protocol+schema) │ └─ ... └─ package.json (声明工作区)

声明工作区后,包之间引用是「目录引用」——@opencode/protocol 依赖 @opencode/schema,解析时直接指向本仓库的 schema 目录,不走 npm。这让包间依赖「即时生效」——改了 schema,protocol 立刻能用上新代码,不用重装。

💡 工作区的价值:它让大型 monorepo 的包间依赖变得像「同一个项目里的模块引用」——即时、透明、无发布开销。这是大型项目能高效开发的基础。

三、版本统一:目录(catalog)

多个包可能用同一个外部依赖(如某工具库)。如果各包各自声明版本,容易出现「A 用 v1、B 用 v2」的版本漂移。OpenCode 用**目录(catalog)**统一:

  • 在一个地方声明所有外部依赖的版本
  • 各包引用这个目录(不直接写版本)
  • 结果:同一依赖在所有包里版本一致

这和 OpenWork 教程讲的 catalog 是同一机制(两个项目都用 pnpm catalog)。版本统一避免了「同一依赖多版本共存」的怪问题。

四、任务编排:增量构建

有几十个包,全量构建很慢。任务编排工具(如 Turborepo)解决增量构建——它理解包间依赖,只重建受影响的:

你改了 schema 包 │ ▼ 任务编排分析依赖图 │ ▼ 找出谁依赖 schema: protocol, core, llm, ... (传递依赖) │ ▼ 只重建这些(及依赖它们的),其余跳过 │ ▼ 增量构建完成

这种「依赖图感知」的增量构建,让「改一个包」的重建范围最小化。对一个几十个包的仓库,这能把构建时间从「全量十几分钟」降到「增量几十秒」。

五、构建顺序:拓扑排序

任务编排还解决「构建顺序」问题。包间有依赖(B 依赖 A),构建时得先建 A 再建 B。编排工具用拓扑排序——按依赖图算出合法的构建顺序:

依赖图: schema ← protocol ← core ← llm ← opencode │ ▼ 拓扑排序 构建顺序: schema → protocol → core → llm → opencode │ ▼ 按此顺序构建,保证被依赖的先建

这和你手动维护「先建谁后建谁」的脚本相比,是质的飞跃——加新包、改依赖,排序自动更新。

六、并行构建

除了顺序,编排工具还能并行——没有依赖关系的包可以同时建(多核利用):

A、B 互不依赖 ──► 并行建(同时) │ C 依赖 A、B ──► 等 A、B 建完再建

这让大型仓库的构建充分利用多核,进一步加速。

七、为什么这种编排适合大型 monorepo

总结这套编排为什么适合大型 monorepo:

挑战 编排如何解决
包间依赖 工作区目录引用,即时生效
版本漂移 catalog 统一版本
全量构建慢 依赖图感知增量,只重建受影响
构建顺序 拓扑排序自动算
多核利用 无依赖包并行建

这五点合起来,让「几十个包的仓库」依然能高效开发——加包、改依赖、增量构建,都自动处理。这是 OpenCode 这种规模项目能持续演进的基础。

八、本节要点回顾

  1. 大型 monorepo 挑战:包间依赖、版本统一、增量构建、构建顺序。
  2. 工作区:包间目录引用,即时生效,无发布开销。
  3. catalog 统一版本:一处声明,各包引用,避免版本漂移。
  4. 任务编排增量:依赖图感知,只重建受影响的包。
  5. 拓扑排序:自动算构建顺序,被依赖的先建。
  6. 并行构建:无依赖包同时建,利用多核。
  7. 适合大型:加包/改依赖/增量都自动,支撑持续演进。

源码管理讲清了,下一节讲怎么把源码变成可执行——单文件构建。


发布者: 作者: 灏天文库 转发
评论区 (0)
U