1. 1. TypeScript 3.0 的 References 工程引用 和 --build 模式
  2. 2. Vite 项目中 tsconfig.json、tsconfig.app.json 和 tsconfig.node.json 的结构
    1. 2.1. 1. 各个配置文件的含义
      1. 2.1.1. ✅ 1.1 tsconfig.json主配置文件
      2. 2.1.2. ✅ 1.2 tsconfig.app.json
  3. 3. compilerOptions.tsBuildInfoFile:指定了 TypeScript 构建的增量编译信息文件位置,这对于快速的增量构建非常重要。#### ✅ 1.3 tsconfig.node.json用于 Node.js 环境的配置,针对 Vite 和服务器端代码优化了 TypeScript 设置。这里是指vite打开的本地服务器。- 示例: 12345678910111213141516171819202122232425{"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"]}
  4. 4. 为什么要拆分多个配置文件?
  5. 5. 使用 --build 和 References 工程引用 的优势
    1. 5.1. 1. 大型单体仓库(Monorepo)
    2. 5.2. 2. 多包项目(例如 npm 包开发)
  6. 6. 使用 project references 示例
    1. 6.1. 项目结构
    2. 6.2. 主项目 tsconfig.json
    3. 6.3. module-a 的 tsconfig.json
      1. 6.3.1. module-a/index.ts
    4. 6.4. module-b 的 tsconfig.json
      1. 6.4.1. module-b/index.ts
    5. 6.5. 构建并运行
    6. 6.6. 控制台输出
  7. 7. 结论

什么是TypeScript中的References 工程引用?

TypeScript 3.0 的 References 工程引用--build 模式

TypeScript 3.0 引入了 References 工程引用--build 模式,这些功能为大型项目和复杂架构提供了强大的工具。通过这些功能,你可以将一个 TypeScript 项目拆分成多个子项目(模块),并且能够更高效地进行增量编译和构建。


Vite 项目中 tsconfig.jsontsconfig.app.jsontsconfig.node.json 的结构

使用npm init vite@latest创建的 Vue3 项目中,会有3个tsconfig.json文件。tsconfig.jsontsconfig.app.jsontsconfig.node.json 通常用于区分不同的环境配置,提高可维护性和灵活性。这种结构一般用于区分 前端(应用层)后端(Node.js 层),或者在构建开发阶段分别使用不同的配置。

1. 各个配置文件的含义

1.1 tsconfig.json主配置文件

  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "files": [],
    "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
    ]
    }

    files:这个配置文件没有直接列出任何文件,主要通过 references 来引用其他配置文件。
    references:指定了 tsconfig.app.json 和 tsconfig.node.json 作为依赖,确保这些文件中的配置会被合并并执行。

1.2 tsconfig.app.json

用于前端应用配置,支持 Vue 3 和 TypeScript,启用了严格模式和增量编译。

  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "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打开的本地服务器。
- 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"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"]
}

为什么要拆分多个配置文件?

  1. 环境差异
  • 前端和后端使用不同的模块系统(ESModules vs CommonJS)。
  • 需要不同的构建工具配置(如 Vite 和 Node.js)。
  1. 构建效率
    这种配置文件结构有助于保持前后端代码独立,并通过增量编译提高构建效率。

使用 --buildReferences 工程引用 的优势

1. 大型单体仓库(Monorepo)

  • 场景:多个前端项目或子模块共享公共库、工具函数或组件库。
    例如,一个大型电商平台可能有多个独立模块(用户管理、订单管理、支付系统等),但共享一些公共组件库或工具包。
  • 优势
    • 每个子项目或库有独立的 tsconfig.json,并通过 references 配置管理依赖。
    • 使用 --build 增量构建,避免全局重新编译,提高构建效率。
    • 清晰的依赖关系和编译边界,减少编译时间。

2. 多包项目(例如 npm 包开发)

  • 场景:开发多个 npm 包,每个包都有独立的 tsconfig.json,但共享通用的类型定义或配置。
    例如,一个 UI 组件库,将不同的组件分为独立的包(如按钮、表格、下拉菜单),但共享公共类型定义。
  • 优势
    • 每个包可以独立发布和版本管理。
    • 通过 --buildreferences 配置,进行依赖管理和高效增量构建。

使用 project references 示例

项目结构

1
2
3
4
5
6
7
8
/my-project
/module-a
tsconfig.json
index.ts
/module-b
tsconfig.json
index.ts
tsconfig.json

主项目 tsconfig.json

在主项目的 tsconfig.json 中,启用 composite,并使用 references 来引用各个子模块(如 module-amodule-b)。

1
2
3
4
5
6
7
8
// root-level tsconfig.json
{
"files": [],
"references": [
{ "path": "./module-a" },
{ "path": "./module-b" }
]
}
  • **composite**:启用增量编译。
  • **references**:指定模块的依赖关系,TypeScript 会按顺序编译这些模块。

module-atsconfig.json

1
2
3
4
5
6
7
8
9
// module-a/tsconfig.json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "../dist/module-a"
},
"include": ["index.ts"]
}
  • **rootDir**:指定源代码的根目录。
  • **outDir**:编译输出目录。
  • **include**:指定要编译的文件。

module-a/index.ts

1
2
3
4
// module-a/index.ts
export function add(a: number, b: number): number {
return a + b;
}

module-btsconfig.json

module-b 引用了 module-a,这意味着在编译 module-b 时,module-a 会先被编译。

1
2
3
4
5
6
7
8
9
10
11
12
// 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

1
2
3
4
5
6
// 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 函数
}

构建并运行

  1. 使用 tsc --build 命令进行构建:
1
tsc --build
  1. 运行编译后的代码:
1
node dist/module-b/index.js

控制台输出

1
6

结论

  • 使用 References 工程引用--build 模式 可以极大提升大型 TypeScript 项目的编译效率,特别是在多模块或多包的情况下。
  • Vite创建的Vue项目中会有三个tsconfig,tsconfig.jsontsconfig.app.jsontsconfig.node.json 的拆分,可以帮助区分不同环境的 TypeScript 配置,确保不同环境下的编译需求和工具设置不冲突。