03-composite项目引用
分类:2-技术文章/02-TypeScript全栈开发/TS基础与类型系统/04-TypeScript类型系统
发布于:
阅读时间:14 分钟
可以把
composite: true如果没有它,你的项目只是一个普通的文件夹;有了它,你的项目就变成了一个可以被其他项目引用、支持增量编译的独立模块。
以下是通俗的拆解:
1. 核心比喻:从“散沙”到“积木”
-
没有
(普通项目):composite: true- 就像一堆散沙。你可以把它们倒进模具(编译)变成砖头。
- 但是,你不能直接拿这堆沙子去盖另一栋楼。如果你想复用,只能把整个沙子堆复制过去,或者重新烧制。
- 缺点:每次构建都要把所有文件重新过一遍,无法利用之前的构建结果。
-
开启
(复合项目):composite: true- 就像把沙子烧制成了标准的乐高积木块。
- 一旦烧制完成(编译生成 和
.tsbuildinfo),它就定型了。.d.ts - 优点:
- 可被引用:其他项目可以直接“插”在这个积木上(通过 )。
references - 状态记录:它会生成一个 文件,记录“我上次是什么时候烧制的,哪些部分变了”。
.tsbuildinfo - 增量加速:如果我没变,别人用我的时候,就不需要重新烧制我,直接用现成的积木即可。
- 可被引用:其他项目可以直接“插”在这个积木上(通过
2. 技术层面的三个关键作用
当你设置
"composite": trueA. 强制生成 .tsbuildinfo
文件 (增量编译的基石)
.tsbuildinfo- 作用:这是 TS 的“存档文件”。它记录了项目中每个文件的版本哈希值和依赖关系。
- 效果:下次编译时,TS 先读这个文件。如果发现某个文件没变,直接跳过该文件的类型检查和代码生成。
- 前提:必须配合 (开启 composite 会自动开启 incremental)。
incremental: true
B. 强制生成声明文件 (.d.ts
)
.d.ts- 作用:复合项目必须输出类型声明。
- 原因:因为其他项目要引用你。引用者不需要看你的源码实现(),只需要看你的接口定义(
.ts)。.d.ts - 限制:如果你设置了 但忘了开
composite: true,TS 会直接报错,因为它无法在不生成声明的情况下被安全引用。declaration: true
C. 启用严格的输入/输出隔离
- 作用:TS 会严格检查 和
rootDir。outDir - 效果:确保源码文件和输出文件不会混在一起。这是为了保证构建结果的纯净,防止把测试代码或临时文件意外发布出去。
3. 实战场景:为什么 Monorepo 必须用它?
假设你有两个包:
coreapp如果不加 :composite: true
- 引用
app的源码。core - 每次修改 的一行代码,TS 为了保险起见,可能会重新扫描
app的所有文件来确认类型没变。core - 随着项目变大,编译时间线性增长,甚至指数级增长。
加上 后:composite: true
- 构建 :TS 编译
core,生成core和core.d.ts。core.tsbuildinfo - 构建 :
app- 的
app里写着tsconfig.json。"references": [{ "path": "../core" }] - TS 看到 是复合项目,于是只读取
core生成的core和.d.ts。.tsbuildinfo - 关键点:TS 完全不看 的源代码(
core文件)。.ts
- 修改 :
app- TS 发现 的
core显示.tsbuildinfo没变。core - TS 跳过 对 的所有处理,只编译
core。app - 速度提升:从“编译整个仓库”变成了“只编译当前修改的模块”。
- TS 发现
4. 总结对照表
| 特性 | 普通项目 ( | 复合项目 ( |
|---|---|---|
| 主要用途 | 单个应用、简单脚本 | Monorepo 子包、大型库、多项目协作 |
| 增量编译 | 可选 ( | 强制开启 (必须生成 |
| 声明文件 | 可选 | 强制开启 (必须生成 |
| 被引用能力 | ❌ 不能被 | ✅ 可以被其他项目引用 |
| 构建命令 | | |
| 依赖处理 | 扁平化,所有文件一起算 | 模块化,依赖项通过 |
一句话理解
就是告诉 TypeScript:“请把我当成一个独立的、可复用的、带版本记录的‘黑盒’模块来处理,别让我跟其他代码混成一锅粥。”composite: true
在 Monorepo 架构中,每一个子包(package)的 都必须开启 tsconfig.json。composite: true