TypeScript 3.0 的 References 工程引用 和 --build 模式
TypeScript 3.0 引入了 References 工程引用 和 --build 模式,工程引用是TypeScript 3.0的新特性,它支持将TypeScript程序的结构分割成更小的组成部分。这样可以改善构建时间,强制在逻辑上对组件进行分离,更好地组织你的代码。--build标记,它与工程引用协同工作可以加速TypeScript的构建。
Vite 项目中 tsconfig.json、tsconfig.app.json 和 tsconfig.node.json 的结构
使用npm init vite@latest创建的 Vue3 项目中,会有3个tsconfig.json文件。分别为tsconfig.json、tsconfig.app.json 和 tsconfig.node.json。
通常用于区分不同的环境配置,提高可维护性和灵活性。这种结构一般用于区分 前端(应用层) 和 后端(Node.js 层),或者在构建和开发阶段分别使用不同的配置。
1. 各个配置文件的含义
✅ 1.1 tsconfig.json主配置文件
- 示例:
{ "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] }
references:指定了 tsconfig.app.json 和 tsconfig.node.json 作为依赖,确保这些文件中的配置会被合并并执行。
✅ 1.2 tsconfig.app.json
用于前端应用配置,支持 Vue 3 和 TypeScript,启用了严格模式和增量编译。
- 示例:
{ "extends": "@vue/tsconfig/tsconfig.dom.json", "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] }
extends:继承了 @vue/tsconfig/tsconfig.dom.json,这是 Vue 官方推荐的基础配置,专为 Vue 3 项目定制,提供了对 Vue 文件的支持。
compilerOptions.tsBuildInfoFile:指定了 TypeScript 构建的增量编译信息文件位置。
✅ 1.3 tsconfig.node.json
用于 Node.js 环境的配置,针对 Vite 和服务器端代码优化了 TypeScript 设置。这里是指vite打开的本地服务器。
- 示例:
{ "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["vite.config.ts"] }
为什么要拆分多个配置文件?
- 环境差异
- 前端和后端使用不同的模块系统(
ESModulesvsCommonJS)。 - 需要不同的构建工具配置(如 Vite 和 Node.js)。
- 构建效率
这种配置文件结构有助于保持前后端代码独立,并通过增量编译提高构建效率。
使用 --build 和 References 工程引用 的优势
1. 大型单体仓库(Monorepo)
- 场景:多个前端项目或子模块共享公共库、工具函数或组件库。
例如,一个大型电商平台可能有多个独立模块(用户管理、订单管理、支付系统等),但共享一些公共组件库或工具包。 - 优势:
- 每个子项目或库有独立的
tsconfig.json,并通过references配置管理依赖。 - 使用
--build增量构建,避免全局重新编译,提高构建效率。 - 清晰的依赖关系和编译边界,减少编译时间。
- 每个子项目或库有独立的
2. 多包项目(例如 npm 包开发)
- 场景:开发多个 npm 包,每个包都有独立的
tsconfig.json,但共享通用的类型定义或配置。
例如,一个 UI 组件库,将不同的组件分为独立的包(如按钮、表格、下拉菜单),但共享公共类型定义。 - 优势:
- 每个包可以独立发布和版本管理。
- 通过
--build和references配置,进行依赖管理和高效增量构建。
使用 project references 示例
项目结构
/my-project
/module-a
tsconfig.json
index.ts
/module-b
tsconfig.json
index.ts
tsconfig.json
主项目 tsconfig.json
在主项目的 tsconfig.json 中,启用 composite,并使用 references 来引用各个子模块(如 module-a 和 module-b)。
// root-level tsconfig.json
{
"files": [],
"references": [
{ "path": "./module-a" },
{ "path": "./module-b" }
]
}
//tsconfig.base.json
{
"compilerOptions": {
"declaration": true,
"target": "es5",
"module": "commonjs",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"composite": true,
}
}
composite:启用增量编译。references:指定模块的依赖关系,TypeScript 会按顺序编译这些模块。
module-a 的 tsconfig.json
// module-a/tsconfig.json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "../dist/module-a"
},
"include": ["index.ts"]
}
rootDir:指定源代码的根目录。outDir:编译输出目录。include:指定要编译的文件。
module-a/index.ts
// module-a/index.ts
export function add(a: number, b: number): number {
return a + b;
}
module-b 的 tsconfig.json
module-b 引用了 module-a,这意味着在编译 module-b 时,module-a 会先被编译。
// module-b/tsconfig.json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "../dist/module-b",
"rootDir": "."
},
"include": ["index.ts"],
"references": [
{ "path": "../module-a" } // 引用 module-a
]
}
module-b/index.ts
// module-b/index.ts
import { add } from "../module-a/index.js";
export function calculate(a: number, b: number): number {
return add(a, b) * 2; // 使用 module-a 中的 add 函数
}
构建并运行
- 使用
tsc --build命令进行构建:
tsc --build
- 运行编译后的代码:
node dist/module-b/index.js
控制台输出
6
注意点:
- 使用
tsc -b --verbose可以查看构建流程。包括构建文件顺序,哪些文件被重新编译,哪些文件跳过编译(因为没有变化)等。 - 使用tsc进行ts编译并不能直接将module-b的引用路径转化为正确的路径。因此需要保证构建产物仍然保持与源文件一致的文件结构。
结论
- 使用 References 工程引用 和
--build模式 可以极大提升大型 TypeScript 项目的编译效率,特别是在多模块或多包的情况下。 - Vite创建的Vue项目中会有三个tsconfig,
tsconfig.json、tsconfig.app.json和tsconfig.node.json的拆分,可以帮助区分不同环境的 TypeScript 配置,确保不同环境下的编译需求和工具设置不冲突。