在 Vue 3 + Vite + TypeScript 项目中,类型检查通常是构建流程的一部分。当项目拆分出应用源码、Node.js 配置和 Vitest 测试代码后,如何组织类型检查、利用增量构建并缩短构建时间,就成为值得关注的工程问题。
一、理解 vue-tsc --build
1. Build Mode 的作用
vue-tsc 用于检查 TypeScript 和 Vue 单文件组件中的类型。--build 则启用 TypeScript 的项目构建模式(Build Mode),负责协调项目及其依赖。 Build Mode 可以:
- 根据
references发现被引用的项目。 - 按依赖关系确定构建顺序。
- 判断项目是否需要重新构建。
- 利用增量构建信息,减少重复工作。
需要注意:--build 不等于 vite build。前者负责 TypeScript 项目构建与协调,后者负责前端应用打包。
2. Project References 与多配置
现代 Vue 项目通常会按代码职责拆分 tsconfig,根配置通过 references 组织子项目:
json
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.test.json" }
]
}
Build Mode 会根据项目引用关系处理子项目。需要注意,各子项目仍需正确配置文件范围、编译选项和项目引用。
多份 tsconfig 并不自动意味着必须使用 --build 。关键在于是否建立了 Project References,以及是否需要统一协调这些项目。
即使只有一个普通 tsconfig.json,也可以使用 --build;不过,如果只是简单地检查类型,普通检查模式可能更直接。
二、现代 Vue 项目的配置实践
1. 为不同项目指定独立配置
应用、Node.js 和测试代码通常有不同的运行环境及类型依赖,应分别设置适合自己的编译选项。
例如,应用配置处理 Vue 组件,Node 配置处理 Vite 配置文件,测试配置引入 Vitest 类型。
这样可以明确每个项目的检查边界,避免测试环境的全局类型不必要地影响应用代码。
2. 配置 tsBuildInfoFile
Build Mode 可以使用 .tsbuildinfo 文件保存增量构建信息。tsBuildInfoFile 用于指定该文件的存储路径。
例如,在 tsconfig.app.json 中:
json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo"
}
}
其他项目应使用独立的文件路径,例如:
tsconfig.node.tsbuildinfotsconfig.test.tsbuildinfo
这样可以避免不同项目共用同一个构建信息文件。
.tsbuildinfo 只用于构建优化,不影响应用运行,可以安全删除。tsBuildInfoFile 用于指定路径,并不单独开启增量构建;具体行为还取决于 TypeScript 的构建模式和相关配置。<Cite refs={"turn144874search1","turn144874search3"}/>
三、工程实践:类型检查与代码打包
1. 使用 npm scripts 组织任务
类型检查和应用打包职责不同,可以拆分为独立脚本:
json
{
"scripts": {
"type-check": "vue-tsc --build",
"build-only": "vite build"
}
}
2. 并行执行类型检查与打包
如果两项任务互不依赖,可以使用 npm-run-all2 并行执行。
配置脚本:
json
{
"scripts": {
"type-check": "vue-tsc --build",
"build-only": "vite build",
"build": "run-p type-check build-only"
}
}
run-p 会同时启动类型检查和 Vite 打包,避免两项任务串行等待。
需要注意,npm-run-all2 默认采用失败即停止其他任务的策略。因此,如果类型检查失败,正在运行的打包任务可能被终止。如果希望打包仍然继续完成,需要单独配置失败处理策略。
并行执行能够缩短构建耗时,但打包产物生成成功,并不代表类型检查通过。CI 应以整个构建命令的退出状态判断最终结果。
四、补充:vue-tsc --noEmit
--noEmit 是普通类型检查模式:
它检查指定配置覆盖的文件,不输出编译后的 JavaScript 文件,适合普通单项目类型检查。
两种模式的核心区别:
--noEmit:直接执行类型检查。--build:按照项目构建模式处理项目及其依赖,并支持增量构建机制。
选择时应考虑项目引用关系和检查需求,而不是仅根据 tsconfig 的数量决定。
总结
- 使用 Project References 组织多个 TypeScript 项目时,可以使用
vue-tsc --build统一调度。 - 通过
tsBuildInfoFile管理增量构建信息,并为不同项目设置独立路径。 - 使用
npm-run-all2并行执行类型检查与 Vite 打包,缩短构建时间。 - 普通单项目可以使用
vue-tsc --noEmit,让类型检查职责更加明确。