为什么有的 JSON 可以带注释?

如果你写过 TypeScript,应该对下面这个文件再熟悉不过了:

json 复制代码
{
  /* Visit https://aka.ms/tsconfig to read more about this file */
  "compilerOptions": {
    "target": "ES2022",
    "strict": true
  }
}

等等......

JSON 不是不能写注释吗?

按照 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 解析器都会直接报错。

json 复制代码
{
  // 用户名
  "name": "Tom",
}

那为什么带注释更好?

虽然 JSON 不支持注释,但配置文件却特别需要它。

举个例子, 没有注释:

json 复制代码
{
  "strict": true,
  "module": "NodeNext",
  "target": "ES2022"
}

对于新人来说:strict 是什么?为什么 target 要写 ES2022?完全不知道。

而有了注释以后:

json 复制代码
{
  // 开启严格模式,推荐保持 true
  "strict": true,
  // 输出 ES2022 代码
  "target": "ES2022"
}

可读性一下子就提升了。

带注释主要有几个好处:

  • 降低学习成本:配置项可以直接解释用途,不需要频繁查文档。
  • 方便团队协作:告诉其他人为什么这样配置,而不仅仅是配置了什么。
  • 保留上下文:记录一些特殊配置的原因,方便后续维护。
  • 更好的开发体验:很多 IDE 会直接显示注释,阅读配置更加直观。

所以,虽然 JSON 不支持注释,但配置文件非常需要注释。

tsconfig.json 为什么可以写注释?

答案其实很简单:

因为它并不是严格意义上的 JSON。TypeScript 并没有直接使用标准 JSON 解析器。而是使用了一种扩展格式:JSONC(JSON with Comments)。

JSONC 在 JSON 的基础上增加了一些能力:

  • ✅ 单行注释 //
  • ✅ 多行注释 /* */

例如:

json 复制代码
{
  // 输出目标
  "target": "ES2022",
  /*
    是否开启严格模式
  */
  "strict": true
}

TypeScript 编译器会先把注释去掉,再按照普通 JSON 解析。

所以:

虽然文件名叫:tsconfig.json, 实际上内容更接近:tsconfig.jsonc 只是为了兼容生态,没有改扩展名而已。

除了 JSONC,还有 JSON5

目前最常见的 JSON 扩展主要有两个。

  1. JSONC

特点:

  • 支持 //
  • 支持 /* */
  • 不支持尾随逗号(部分实现可能会兼容,但规范本身不鼓励)

例如:

json 复制代码
{
  // 用户名
  "name": "Tom"
}

典型使用场景:

  • TypeScript (tsconfig.json)
  • VS Code (settings.json)
  • VS Code 插件配置
  1. JSON5

JSON5 比 JSONC 更进一步。

除了支持注释,还支持:

  • 单引号
  • 尾随逗号
  • 对象 Key 不加引号
  • 十六进制数字
  • Infinity
  • NaN

例如:

json 复制代码
{
  // 用户
  name: 'Tom',
  age: 18,
  skills: [
    'JS',
    'TS',
  ],
}

是不是越来越像 JavaScript 对象了?

很多前端工具都会支持 JSON5,例如:

  • Babel
  • Next.js(部分配置)
  • 各种 Node.js 工具链
哪些工具支持 JSONC?

现在支持 JSONC 的工具已经很多了,例如:

工具 是否支持 JSONC

TypeScript ✅

VS Code ✅

Visual Studio ✅

Azure 配置 ✅

ESLint(部分配置) ✅

Monaco Editor ✅

可以说,只要是现代前端开发,几乎都会接触到 JSONC。

JSONC 怎么转换成标准 JSON?

如果需要把 JSONC 提交给接口、数据库或者其他只支持标准 JSON 的程序,就需要先去掉注释。

常见的方法有:

方案一:使用 npm 包

例如微软提供的:

npm install jsonc-parser

或者:

npm install strip-json-comments

它们都可以自动移除注释,再输出标准 JSON。

方案二:在线转换工具

如果只是偶尔需要转换,不想安装依赖,直接使用在线工具会更加方便。

例如:

👉 ToolGarden

https://toolgarden.xyz

可以直接:

  • 粘贴 JSONC
  • 一键移除注释
  • 输出标准 JSON
  • 复制即可使用

对于临时处理配置文件来说非常方便。

总结

很多人第一次看到 tsconfig.json 能写注释都会觉得奇怪,其实原因很简单:

  • 标准 JSON 不允许注释。
  • TypeScript 使用的是 JSONC(JSON with Comments)。
  • JSONC 是为了让配置文件更易读、更易维护。
  • JSON5 则提供了更多 JavaScript 风格的语法扩展。

对于开发者来说,配置文件带注释几乎已经成为现代工具链的标配。理解 JSON、JSONC 和 JSON5 的区别,也能帮助我们在不同场景下选择合适的数据格式。

下次再看到 tsconfig.json 里的注释,就不用疑惑了------它其实不是严格意义上的 JSON,而是 JSONC。