YAML 是 JSON 数据模型的超集: 每一个合法的 JSON 文档在逐字对照下 也是合法的 YAML。区别不在于每种格式能表示什么, 而在于每种格式 如何书写, 以及每种格式对手动编辑的友好程度。
同样的数据, 两种写法
{
"name": "web-app",
"version": "1.0.0",
"scripts": { "build": "vite build", "test": "vitest" },
"dependencies": ["react", "vite"]
}
name: web-app
version: 1.0.0
scripts:
build: vite build
test: vitest
dependencies:
- react
- vite
同一个文档, 解析后得到同样的数据。YAML 去掉了花括号、方括号、 普通字符串周围的引号以及大部分逗号, 改用缩进来表示嵌套。
真正的区别在哪里
注释。 YAML 有注释, # 这样写。JSON 从设计上就没有注释;
一个 .json 配置文件如果想在某个设置旁边写说明, 就必须把说明
放到别处, 通常是 README 里, 因为解析器会直接拒绝包含 // 或 #
的行。仅凭这一点, 手动维护的配置(CI 流水线、Docker Compose、
Kubernetes 清单)就默认使用 YAML: 一年后来编辑的人需要知道某个
设置为什么是这样, 而注释是唯一能留在值旁边的东西。
空白敏感性。 YAML 的缩进是结构性的, 和 Python 一样。用两个空格 而不是四个, 或者在应该有空格的地方出现了一个制表符, 就会改变 文档的含义或直接破坏文档, 而缩进错误的报错信息通常不如 JSON 解析器的“第 4 行第 12 列出现意外 token”来得明确。JSON 的花括号和 方括号是显式的, 因此缩进只是美观性的, 这也是为什么 JSON 是机器 生成和消费的格式: 脚本不关心可读性, 更倾向于没有歧义的分隔符。
同一值有多种写法。 YAML 有普通标量、单引号字符串、双引号字符串、
用于多行文本的块标量、通过引用来重复值的锚点和别名, 以及一些隐式
类型转换(yes 和 no 在 YAML 1.1 中会被解析为布尔值, 这正是导致
“挪威问题”(国家代码 NO 被读为布尔假值)成为知名 YAML 陷阱的那类
意外)。JSON 只有一种写字符串的方式, 一种写数字的方式, 没有任何
隐式转换。写同一事物的方式越少, 写错的方式就越少, 这才是机器间
负载使用 JSON 的真正理由。
大小(不考虑冗余和注释)。 去掉空白后, JSON 和 YAML 压缩后的 大小大致相当; YAML 的优势在于人工编辑时的可读性, 而非原始字节数。
何时使用哪种
- JSON 用于任何程序生成而另一个程序消费、中间不需要人阅读的场景: API 载荷、数据交换、在同一请求-响应周期中序列化和反序列化的任何内容。
- YAML 用于需要人经常手动编辑、并且需要注释或多行字符串才能保持 可维护性的场景: CI 配置、Kubernetes 清单、自带内联文档的应用配置文件。
很多工具同时接受两者并在内部转换, 这通常比永久选择一方更有用: 用维护者偏好的格式编写配置, 在需要程序化消费的地方转换为 JSON。
互相转换
JSON 转 YAML 转换器 双向运行: 它正确写入锚点、
别名和多文档流, 而非将所有内容扁平化为普通标量; 读回 YAML 时,
它会将任何无法以原始类型往返的内容用引号括起来(如 "1.0.0"
版本字符串仍然是字符串, 而不是数字 1)。你转换的任何内容都不会
被上传; 转换在你的浏览器中运行, 和本站的每个工具一样。