TypeScript 中的 baseUrl 与 paths
说明 baseUrl 与 paths 为什么常被一起提及、它们的职责如何不同,以及现代项目为什么更倾向于减少对 baseUrl 的依赖。
#type / synthesis
#status / growing
#tech / dev
#resource / typescript
[!info] related notes
- 所属 MOC: TypeScript MOC
- 所属 MOC: TypeScript MOC
- 相关概念: TypeScript 中的 baseUrl, TypeScript 中的 paths
- 易混淆概念: Monorepo 中的 tsconfig 实践
- 关系笔记: TypeScript、tsc、tsconfig 与 tsserver 的关系, 编辑器、TypeScript 版本与 tsconfig 诊断结果的关系
TypeScript 中的 baseUrl 与 paths
范围
这篇笔记不再分别定义 baseUrl 和 paths 的全部细节,而是解释为什么它们总被放在一起讨论。
为什么要放在一起理解
它们经常一起出现,是因为历史上很多项目会这样写:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@app/*": ["app/*"]
}
}
}
但它们的职责并不相同:
baseUrl更偏“给裸模块一个额外查找根”paths更偏“把某个模式映射到一组目标路径”
依赖路径 / 调用链 / 演进链
旧习惯
如果你的 baseUrl 只是为了给 paths 提供公共前缀,更推荐改成:
{
"compilerOptions": {
"paths": {
"@app/*": ["./src/app/*"],
"@lib/*": ["./src/lib/*"]
}
}
}
这是因为过去 paths 常和 baseUrl 一起出现。
现代趋势
从 TypeScript 4.1 起,paths 已不再要求必须配置 baseUrl。
因此现代项目的趋势更像:
- 如果只是 alias,优先把路径写显式
- 尽量别再让
baseUrl额外参与裸模块解析
边界与易混淆点
“经常一起用”不等于“应该永远一起写”
这是最常见的历史惯性误解。
拆开后更容易判断该改谁
很多时候你真正该处理的是:
baseUrl参与裸模块解析的问题
或者:
paths与运行时 alias 不一致的问题
把两者分开理解,排障会明显更快。
参考信息
- TypeScript 4.1 Release Notes: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html
- TypeScript 6.0 Release Notes: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-6-0.html