125、【Agent】【OpenCode】项目配置(项目引用)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog

【Agent】【OpenCode】项目配置(tsconfig.json 与 package.json)

继续分析了 export 的配置,export 指向的是源码 .ts 文件,而不是 dist/ 构建产物,因为 Bun 原生支持直接执行 TypeScript,所以支持 exports 通配符可以直接指向源码,接着分析了 package.jsontsconfig.json,子包下唯二的两个 JSON 配置文件,有子包的地方,除了有 package.json,还有 tsconfig.json,其中 package.json 是写给 Node.js 等包管理器看的运行时与依赖契约,负责包级别的连接,而 tsconfig.json 则是写给 TypeScript 编译器看的类型检查与转译指令,负责代码级别的连接,下面继续分析

OpenCode

上篇 blog 提到了 tsconfig.json 的一个作用:项目引用 ,项目应用是 TypeScript 专门为 Monorepo 设计的一套机制,用来解决多个子包之间互相依赖时,如何高效进行类型检查和编译的问题 ,可以将其理解为 tsconfig.json 层面的 workspace(根目录的 package.json 才有的那个工作区)

如果没有项目引用 references ,假设现在 Monorepo 有三个包:appcoreutils(箭头表示依赖方向),当在 app 中导入 import 了 core,而 core 又导入 import 了 utils

  • 编译器 tsc 检查上层 app 时,会把 coreutils 的所有源码重新纳入当前编译上下文
  • 改一行下层 utils 的代码,三个包的类型检查都要重新跑一遍
  • 包越多,编译越慢,且容易出现重复声明,类型不一致等稀奇古怪的错误(盘子大了)

有了 references 项目引用,每个包都有自己的 tsconfig.json,并通过 references 显式声明依赖关系,编译器 tsc 就能

  • 独立编译 :每个包只编译自己的代码,产出 *.d.ts 类型的声明文件
  • 增量构建utils 没变(跳过),core 变了(只重编 coreapp
  • 边界清晰app 只能通过 core 的公开导出访问类型,而不能穿透到内部实现

举个例子,被依赖方,比如 packages/utils/tsconfig.json

javascript 复制代码
{
  "compilerOptions": {
    "composite": true,        // ← 🔑 关键!启用项目引用模式
    "declaration": true,      // ← 必须生成 .d.ts
    "declarationMap": true,   // ← 推荐:支持 IDE 跳转到源码
    "outDir": "./dist"
  },
  "include": ["src"]
}

这里 composite: true 是核心开关,会告诉 tsc 编译器,这个包可以被其他项目引用,需要生成类型声明并记录构建信息,可以看到,在 OpenCode,被依赖包并不多

接下来是依赖方,比如 packages/core/tsconfig.json

javascript 复制代码
{
  "compilerOptions": {
    "composite": true
  },
  "references": [
    { "path": "../utils" }    // ← 声明依赖 utils
  ],
  "include": ["src"]
}

注意,这里的 core 之所以开了 composite,是因为可能被 app 所引用(也就是它既是依赖方,又是更上层包的被依赖方),composite: true 不是引用别人的开关,而是可以被别人引用的开关

  • core 引用了 utilscore 需要 references
  • app 引用了 corecore 必须能被引用,所以 composite: true

所以 core 两者都需要,只有最顶层,永远不会被任何包引用的 app 应用,才可以省略 composite

【关于 composite 的含义解释】

composite 出现之前,TypeScript 的规则是一个 tsconfig.json 就是一个完整,不可分割的编译单元,所有文件混在一起编译,产出一堆 JS,这里 composite: true 的意思是,把这个项目变成一个标准化的预制构件,就像乐高积木或建筑中的预制板一样:

  • 它有自己的标准接口(.d.ts 类型声明)
  • 它有自己的质量认证标记(.tsbuildinfo 构建元数据)
  • 它的尺寸是确定的(rootDir 约束保证输出结构稳定)

只有当一个项目被做成了这种标准预制构件(composite),别的项目才能把它当做一个整体模块安全地拼装(references)起来


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog

【Agent】【OpenCode】项目配置(composite)