tsconfig.json 到底配置了个啥?——从凡人到元婴的修仙指南
1、凡人入道:七玄门里的“藏宝图”
最近笔者在倒腾一个 Monorepo 大工程(全栈开发),不可避免地撞上了 tsconfig.json。盯着里面密密麻麻的配置项,我陷入了沉思:我只是想让 tsc 帮我把代码翻译翻译,为什么需要这么多繁琐的指令?
作为一个老牌“码农修仙者”,以前配置这玩意儿全靠搜魂术(Ctrl+C/V),大不了请出AI邪修强行破阵。但为了修得正果,我决定深入禁地,扒一扒这本“编译器操作手册”背后的底层逻辑。
本文不复读文档!!,只论道法。各位道友,请随我入阵!🫡
2、炼气奠基:诸神黄昏与模块化的恩怨
要想修仙修得好,因果背景不能少。
tsconfig.json 之所以复杂,全怪 JS 那些年留下的“情债”。在 JS 道祖开天辟地之初,根本没有模块化。后来江湖大乱,CommonJS、AMD、UMD 割据一方。直到 ES6(2015年),官方才推出了 ES Module (ESM) 试图大一统。
但问题来了:即便现在已是 2026 年,npm 生态里依然残留着海量的 CommonJS 老古董。
TypeScript 作为 JS 的超集,它最核心的痛苦就在于: 它得当一个“翻译官”,协调这些互不兼容的模块体系。
这就是 tsconfig.json 存在的根本意义——它在告诉编译器:在不同模块体系交火时,该如何“拉偏架”!
JSON
{
"compilerOptions": {
"module": "CommonJS", // 告诉 TS:编译出的代码用哪种方言说话
"moduleResolution": "node", // 告诉 TS:去哪里寻找那些失散的模块
"esModuleInterop": true, // 给 ESM 和 CJS 之间搭个桥,别让他们打架
"allowSyntheticDefaultImports": true // 即使对方没写 default,也允许我“默认”导入
}
}
3、筑基风云:深入理解核心阵法
3.1 核心作用:它到底管什么?
简单来说,tsconfig.json 负责两件事: “管人” (哪些文件参战)和 “管事” (怎么打仗)。
-
文件管理(管人):
通过
include、exclude、files划定势力范围。比如:编译src里的天才(源码),踢出node_modules里的路人。 -
编译规则(管事):
- 宿主环境:
target决定你是要在老旧的浏览器(ES5)里爬行,还是在现代引擎(ESNext)里飞升。 - 模块体系:
module决定输出的形状。 - 检查强度:
strict模式。开启后,编译器就像严师,一丝一毫的类型模糊(any)都可能让你道心破碎。
- 宿主环境:
3.2 配置继承:分身之术(Extends)
在 Monorepo 或 Vite 项目中,你会看到 tsconfig.app.json、tsconfig.node.json。
- extends:为了避免每个子项目都写一遍冗长的配置,我们可以搞个“祖传秘籍”(base.json),子项直接继承,只需微调(比如前端需要
DOM库,后端需要Node库)。
3.3 路径解析:缩地成寸(Paths)
受够了 import { tool } from "../../../../../utils" 这种“僵尸路径”?
通过 baseUrl 和 paths,你可以施展缩地成寸:
JSON
"paths": {
"@/*": ["src/*"]
}
道友请留步: 这只是给 tsc 看的“幻术”。如果你没配合 Vite/Webpack 进行物理层面的路径映射,代码运行到 JS 环境时会因为找不到路而走火入魔。
3.4 模块查找:现代修仙的新法门
到了 TS 5.x 时代,有两个配置值得重点关注:
- moduleResolution: "bundler" :这是给 Vite/Webpack 打包工具量身定制的模式。它更聪明,知道现在的开发者不喜欢写
.js后缀,也懂得如何处理package.json里的各种复杂导出。 - verbatimModuleSyntax:这是高性能开关。它要求你明确标记
import type。编译器看到 type 直接“物理删除”,不费脑子去猜,编译速度突飞猛进。
4、结丹:道法总结
要真正掌握 tsconfig.json,只需记住:
- 它是输入的准则:界定哪些文件是你的“门徒”。
- 它是运行的蓝图:决定代码翻译成什么样。
- 它是类型的心法:决定静态检查有多狠。
5、元婴出世:下一步挑战
修炼至此,你已经识破了 tsconfig.json 的伪装。面对深不可测的 Monorepo 配置,你已经具备了初步的抗性。
好了,现在各位可以去挑战韩老魔了,加油~