我的博客
返回首页

03-composite项目引用

分类:2-技术文章/02-TypeScript全栈开发/TS基础与类型系统/04-TypeScript类型系统
发布于:
阅读时间:14 分钟

可以把

composite: true
理解为 TypeScript 项目中的 “身份证”“准入证”

如果没有它,你的项目只是一个普通的文件夹;有了它,你的项目就变成了一个可以被其他项目引用、支持增量编译的独立模块

以下是通俗的拆解:

1. 核心比喻:从“散沙”到“积木”

  • 没有

    composite: true
    (普通项目)

    • 就像一堆散沙。你可以把它们倒进模具(编译)变成砖头。
    • 但是,你不能直接拿这堆沙子去盖另一栋楼。如果你想复用,只能把整个沙子堆复制过去,或者重新烧制。
    • 缺点:每次构建都要把所有文件重新过一遍,无法利用之前的构建结果。
  • 开启

    composite: true
    (复合项目)

    • 就像把沙子烧制成了标准的乐高积木块
    • 一旦烧制完成(编译生成
      .tsbuildinfo
      .d.ts
      ),它就定型了。
    • 优点
      1. 可被引用:其他项目可以直接“插”在这个积木上(通过
        references
        )。
      2. 状态记录:它会生成一个
        .tsbuildinfo
        文件,记录“我上次是什么时候烧制的,哪些部分变了”。
      3. 增量加速:如果我没变,别人用我的时候,就不需要重新烧制我,直接用现成的积木即可。

2. 技术层面的三个关键作用

当你设置

"composite": true
时,TypeScript 编译器会强制开启以下三个行为:

A. 强制生成
.tsbuildinfo
文件 (增量编译的基石)

  • 作用:这是 TS 的“存档文件”。它记录了项目中每个文件的版本哈希值和依赖关系。
  • 效果:下次编译时,TS 先读这个文件。如果发现某个文件没变,直接跳过该文件的类型检查和代码生成。
  • 前提:必须配合
    incremental: true
    (开启 composite 会自动开启 incremental)。

B. 强制生成声明文件 (
.d.ts
)

  • 作用:复合项目必须输出类型声明。
  • 原因:因为其他项目要引用你。引用者不需要看你的源码实现(
    .ts
    ),只需要看你的接口定义(
    .d.ts
    )。
  • 限制:如果你设置了
    composite: true
    但忘了开
    declaration: true
    ,TS 会直接报错,因为它无法在不生成声明的情况下被安全引用。

C. 启用严格的输入/输出隔离

  • 作用:TS 会严格检查
    rootDir
    outDir
  • 效果:确保源码文件和输出文件不会混在一起。这是为了保证构建结果的纯净,防止把测试代码或临时文件意外发布出去。

3. 实战场景:为什么 Monorepo 必须用它?

假设你有两个包:

core
(核心库) 和
app
(应用)。

如果不加

composite: true

  1. app
    引用
    core
    的源码。
  2. 每次修改
    app
    的一行代码,TS 为了保险起见,可能会重新扫描
    core
    的所有文件来确认类型没变。
  3. 随着项目变大,编译时间线性增长,甚至指数级增长。

加上

composite: true
后:

  1. 构建
    core
    :TS 编译
    core
    ,生成
    core.d.ts
    core.tsbuildinfo
  2. 构建
    app
    • app
      tsconfig.json
      里写着
      "references": [{ "path": "../core" }]
    • TS 看到
      core
      是复合项目,于是只读取
      core
      生成的
      .d.ts
      .tsbuildinfo
    • 关键点:TS 完全不看
      core
      的源代码(
      .ts
      文件)。
  3. 修改
    app
    • TS 发现
      core
      .tsbuildinfo
      显示
      core
      没变。
    • TS 跳过
      core
      的所有处理,只编译
      app
    • 速度提升:从“编译整个仓库”变成了“只编译当前修改的模块”。

4. 总结对照表

特性普通项目 (
composite: false
)
复合项目 (
composite: true
)
主要用途单个应用、简单脚本Monorepo 子包、大型库、多项目协作
增量编译可选 (
incremental: true
)
强制开启 (必须生成
.tsbuildinfo
)
声明文件可选强制开启 (必须生成
.d.ts
)
被引用能力❌ 不能被
references
引用
✅ 可以被其他项目引用
构建命令
tsc
tsc -b
(Build mode)
依赖处理扁平化,所有文件一起算模块化,依赖项通过
.d.ts
隔离

一句话理解

composite: true
就是告诉 TypeScript:“请把我当成一个独立的、可复用的、带版本记录的‘黑盒’模块来处理,别让我跟其他代码混成一锅粥。”

在 Monorepo 架构中,每一个子包(package)的

tsconfig.json
都必须开启
composite: true

TypeBox + Elysia Eden 类型膨胀