如果你写过 TypeScript,应该对下面这个文件再熟悉不过了:
{
/* Visit https://aka.ms/tsconfig to read more about this file */
"compilerOptions": {
"target": "ES2022",
"strict": true
}
}等等……
JSON 不是不能写注释吗?
按照 JSON 标准,下面这样的写法其实都是非法的:
// 这是单行注释
{
"name": "ChatGPT"
}
{
/*
这是多行注释
*/
"name": "ChatGPT"
}可为什么 tsconfig.json、settings.json、launch.json 等配置文件却可以愉快地写注释?今天就聊聊背后的原因。
JSON 为什么不能有注释?
JSON(JavaScript Object Notation)最初的目标就是数据交换格式。
简单、统一、容易解析。
因此官方 JSON 规范(RFC 8259)里并没有注释。标准 JSON 只允许这些元素:
- 对象(Object)
- 数组(Array)
- 字符串
- 数字
- Boolean
- null
除此之外,注释、尾随逗号、单引号全部都不允许。
所以像下面这样的文件,标准 JSON 解析器都会直接报错。
{
// 用户名
"name": "Tom",
}那为什么带注释更好?
虽然 JSON 不支持注释,但配置文件却特别需要它。
举个例子,没有注释:
{
"strict": true,
"module": "NodeNext",
"target": "ES2022"
}对于新人来说:strict 是什么?为什么 target 要写 ES2022?完全不知道。
而有了注释以后:
{
// 开启严格模式,推荐保持 true
"strict": true,
// 输出 ES2022 代码
"target": "ES2022"
}可读性一下子就提升了。带注释主要有几个好处:
- 降低学习成本:配置项可以直接解释用途,不需要频繁查文档。
- 方便团队协作:告诉其他人为什么这样配置,而不仅仅是配置了什么。
- 保留上下文:记录一些特殊配置的原因,方便后续维护。
- 更好的开发体验:很多 IDE 会直接显示注释,阅读配置更加直观。
所以,虽然 JSON 不支持注释,但配置文件非常需要注释。
tsconfig.json 为什么可以写注释?
答案其实很简单:因为它并不是严格意义上的 JSON。TypeScript 并没有直接使用标准 JSON 解析器,而是使用了一种扩展格式:JSONC(JSON with Comments)。
JSONC 在 JSON 的基础上增加了一些能力:
- 单行注释 //
- 多行注释 /* */
例如:
{
// 输出目标
"target": "ES2022",
/*
是否开启严格模式
*/
"strict": true
}TypeScript 编译器会先把注释去掉,再按照普通 JSON 解析。
所以,虽然文件名叫 tsconfig.json,实际内容更接近 tsconfig.jsonc。只是为了兼容生态,它没有改扩展名而已。
除了 JSONC,还有 JSON5
目前最常见的 JSON 扩展主要有两个。
1. JSONC
JSONC 的特点很克制:支持单行注释和多行注释,但不鼓励尾随逗号,整体仍然接近标准 JSON。
{
// 用户名
"name": "Tom"
}典型使用场景包括 TypeScript 的 tsconfig.json、VS Code 的 settings.json、launch.json,以及 VS Code 插件配置。
2. JSON5
JSON5 比 JSONC 更进一步。除了支持注释,还支持单引号、尾随逗号、对象 key 不加引号、十六进制数字、Infinity 和 NaN。
{
// User
name: 'Tom',
age: 18,
skills: [
'JS',
'TS',
],
}是不是越来越像 JavaScript 对象了?很多前端工具都会支持 JSON5,例如 Babel、Next.js 的部分配置,以及各种 Node.js 工具链。
哪些工具支持 JSONC?
现在支持 JSONC 的工具已经很多了。可以说,只要是现代前端开发,几乎都会接触到 JSONC。
| 工具 | 是否支持 JSONC |
|---|---|
| TypeScript | 支持 |
| VS Code | 支持 |
| Visual Studio | 支持 |
| Azure 配置 | 支持 |
| ESLint(部分配置) | 支持 |
| Monaco Editor | 支持 |
JSONC 怎么转换成标准 JSON?
如果需要把 JSONC 提交给接口、数据库或者其他只支持标准 JSON 的程序,就需要先去掉注释。
方案一:使用 npm 包
例如微软提供的 jsonc-parser,或者 strip-json-comments。它们都可以自动移除注释,再输出标准 JSON。
npm install jsonc-parser
npm install strip-json-comments方案二:在线转换工具
如果只是偶尔需要转换,不想安装依赖,直接使用在线工具会更加方便。
总结
很多人第一次看到 tsconfig.json 能写注释都会觉得奇怪,其实原因很简单:标准 JSON 不允许注释;TypeScript 使用的是 JSONC(JSON with Comments);JSONC 是为了让配置文件更易读、更易维护;JSON5 则提供了更多 JavaScript 风格的语法扩展。
对于开发者来说,配置文件带注释几乎已经成为现代工具链的标配。理解 JSON、JSONC 和 JSON5 的区别,也能帮助我们在不同场景下选择合适的数据格式。
下次再看到 tsconfig.json 里的注释,就不用疑惑了。它其实不是严格意义上的 JSON,而是 JSONC。