JSON 转 YAML 实用指南:配置文件读起来更顺手
讲清楚 JSON 转 YAML 在 K8s、CI、配置文件里的真实用途,缩进语法怎么数空格,多行字符串用块标量,以及两者本质区别,附一段真实转换示例。
JSON 转 YAML 实用指南:配置文件读起来更顺手
写 Kubernetes manifest、GitHub Actions workflow、docker-compose 的人,迟早会遇到一个场景:手里有一段 JSON,要把它塞进一份 YAML 配置里。直接抄进去不行,JSON 的花括号和引号在 YAML 里又丑又容易出错。这时候就需要把 JSON 转成 YAML。这篇文章把转换的几个关键点讲清楚:为什么转、缩进怎么数、多行字符串怎么处理、它和 JSON 到底差在哪。
为什么要把 JSON 转成 YAML
JSON 是给机器读的,YAML 是给人读的。API 响应、数据库导出、前端打包产物,基本都是 JSON。但运维和 CI 这一层的配置,主流都用 YAML:Kubernetes 的 manifest、GitLab CI 和 GitHub Actions 的流水线、docker-compose、Ansible playbook,清一色 YAML。
差别在哪?同一份配置,JSON 满屏 {、}、"、,,层级一深就得靠编辑器折叠才看得清。YAML 把这些符号全省了,靠缩进表达层级,一眼就能看出谁包着谁。配置文件是要反复人工 review、手改、code review 的东西,可读性直接决定改起来会不会出错。所以拿到一段 JSON,转成 YAML 再提交,几乎是个固定动作。
如果你手头是反方向的需求,比如把一份 YAML 配置喂给只吃 JSON 的接口,可以用 /zh/t/yaml-to-json/ 反向转。
缩进语法:YAML 靠空格分层级,且只能用空格
这是 YAML 最该先搞懂的一条规则:层级完全由缩进决定,而且缩进只能用空格,不能用 Tab。YAML 规范明确禁止 Tab 缩进,很多解析报错追到底就是有人手敲了一个 Tab。
同一层的键,缩进必须对齐到同一列。子级比父级多缩进几个空格都行(2 个或 4 个),但同一份文件里要统一。Kubernetes、GitHub Actions、docker-compose 习惯都用 2 空格,这也是为什么转换时缩进默认给 2:贴进这些工具不会在 review 里显得突兀。
数组用 - 开头的行表示,每个 - 是一个元素:
ports:
- 8080
- 9090
对象的键直接 键: 值,注意冒号后面那个空格不能省。
多行字符串:用块标量,别用一长行转义
JSON 表达多行文本只能靠 \n 转义,一段 shell 脚本塞进 JSON 字符串就成了一长行,塞满 \n 完全没法读。YAML 有专门的块标量语法解决这件事。
字面块标量用 |- 开头,后面的内容按原样分行保留:
script: |-
npm install
npm run build
npm test
这正是 GitHub Actions 里 run: 步骤想要的形式。把一段跨行命令从 JSON 搬进 YAML,块标量让它恢复成正常分行的样子,不用再手动转义引号。这是 JSON 转 YAML 里可读性提升最明显的一处。
一段真实转换:JSON 进,YAML 出
拿一段典型的服务配置 JSON 来看:
{
"name": "web",
"replicas": 3,
"env": { "DEBUG": "false", "TZ": "Asia/Shanghai" },
"ports": [8080, 9090],
"note": "deploy at 3:30 PM"
}
转成 YAML 后:
name: web
replicas: 3
env:
DEBUG: "false"
TZ: Asia/Shanghai
ports:
- 8080
- 9090
note: "deploy at 3:30 PM"
注意两个细节。DEBUG 的值 "false" 保留了引号,因为它本来就是字符串,不加引号 YAML 会把它当成布尔,Compose 这类工具就可能把开关解析坏。note 里的 3:30 PM 也被加了引号,因为冒号空格在 YAML 里是键值分隔符,不加引号 3:30 会被错读成一个 map key。这种歧义字符的自动加引号,是手抄最容易漏掉的地方。
和 JSON 的本质区别
我自己第一次把一份 docker-compose 从 JSON 风格改 YAML 时,栽在注释上:JSON 根本没有注释语法,所以转出来的 YAML 里也不会凭空出现注释,想要 # 注释行得转完手动补。这一点和很多人的预期相反。
几个核心区别值得记住:JSON 用花括号和方括号划界,YAML 用缩进;JSON 字符串必须双引号,YAML 大部分情况裸写即可,只在歧义时才加引号;JSON 没有注释,YAML 有 #;数据类型上两者都支持字符串、数字、布尔、null、数组、对象,转换时类型会原样保留,true 还是布尔,"true" 还是带引号的字符串。
还有个容易踩的坑:别把 JavaScript 对象字面量当 JSON 粘进来。{ name: 'x', port: 8080, } 里键没引号、用单引号、末尾还有逗号,全是非法 JSON。转换前先确认是严格 JSON,可以先过一遍 /zh/t/json-formatter/ 校验格式。
搞清楚这几点,JSON 转 YAML 就从"凑合抄"变成一个稳定可靠的动作,配置文件读起来顺手,review 时也少出错。
Made by Toolora · Updated 2026-06-13