TypeScript文档要求项目引用需启用composite,但未启用仍可构建,其影响是什么?
composite使用TypeScript项目引用的影响 TypeScript官方项目引用文档指出:
被引用的项目必须启用新的composite设置。
但我使用TypeScript 5.1.6版本时,执行tsc --build命令可正常完成构建。想了解:不启用composite就使用项目引用会产生什么影响?
项目结构
. ├── package.json ├── src1/ │ ├── foo.spec.ts │ └── foo.ts ├── tsconfig.json ├── tsconfig.spec.json └── tsconfig.src.json
./package.json
{ "name": "declaration-file-in-proj-ref", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc --build" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "typescript": "^5.1.6" } }
./src1/foo.spec.ts
export const X = 10;
./src1/foo.ts
export const X = 10;
./tsconfig.json
{ "compilerOptions": { "target": "es2018", "module": "es2015", "lib": [ "es2020", "dom", "DOM.Iterable" ], "allowJs": false, "sourceMap": true, "outDir": "tscbuild", "importHelpers": true, "downlevelIteration": true, "strict": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictBindCallApply": true, "strictPropertyInitialization": true, "alwaysStrict": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "moduleResolution": "node", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "noErrorTruncation": true, }, "references": [ { "path": "./tsconfig.src.json" }, { "path": "./tsconfig.spec.json" }, ], "exclude": [ "." // prevent this config from including all files ] }
./tsconfig.spec.json
{ "extends": "./tsconfig.json", "compilerOptions": { "declaration": true, "noEmit": true, "noImplicitAny": false, "module": "commonjs" }, "include": [ "./src1/**/*.spec.ts", "./src1/**/*.helpers.ts" ], "exclude": [] }
./tsconfig.src.json
{ "extends": "./tsconfig.json", "compilerOptions": { "declaration": true, }, "include": [ "./src1/**/*.ts" ], "exclude": [ "./src1/**/*.spec.ts" ], }
回答
虽然TypeScript 5.x版本出于兼容,允许不启用composite: true就使用项目引用并执行tsc --build,但这并非官方设计的预期行为,会带来以下明确影响:
增量构建完全失效
composite的核心作用之一是生成.tsbuildinfo文件,记录项目的编译状态和依赖关系。不启用的话,tsc --build会跳过增量检查,每次都全量编译所有关联项目,哪怕只有单个文件变更,构建效率会随着项目规模扩大急剧下降。项目依赖顺序无法保证
没有composite标记,TypeScript无法准确识别项目间的依赖层级,可能出现被引用项目未优先编译的情况。在复杂项目中,这会导致编译产物引用未更新的代码,出现逻辑错误或类型不匹配。声明文件管理混乱
你的项目中tsconfig.src.json启用了declaration: true,但不开启composite的话,TypeScript无法确保声明文件被正确生成并被其他依赖项目识别。当项目间存在类型引用时,可能出现找不到类型定义、类型不一致的问题,尤其是在多项目交叉引用的场景下。未来版本兼容性风险
官方文档明确要求被引用项目必须启用composite,当前版本的兼容行为只是临时的。后续TypeScript版本可能会收紧校验,直接拒绝构建未启用composite的引用项目,导致你的构建流程直接失败。
另外,你的tsconfig.spec.json设置了noEmit: true,这个项目本身不需要输出产物,所以暂时没暴露问题,但如果后续调整为需要输出的项目,就会立刻触发上述隐患。
建议你尽快给所有被引用的项目添加"composite": true配置,遵循官方规范,避免后续出现难以排查的构建问题。
内容的提问来源于stack exchange,提问作者Daniel Kaplan

