Tools

怎样比对两个 JSON 文件

两个 JSON 文件原样拿来比对,亮起来的大半什么都不是:缩进、折行、顺序不同的键。药方不是更聪明的比对——是先把两个文件过同一个格式化器,让剩下的只有真差异。两步都跑在你的浏览器里,而装着机密的配置文件就该待在那儿。

打开文本比对 两段文本进来,每处差异都被标出来,逐行、逐词。没有一个字被贴进别人的服务器。

以 Markdown 查看

简短的答案

  1. 打开 JSON 格式化,贴入第一个文件,缩进设成两个空格,勾上“排序每个对象的键”。复制结果。
  2. 打开文本比对,贴进左边的框。
  3. 第二个文件照做,贴进右边的框。

结果更容易阅读。改过的值、新增的键、删除的条目会更清楚。原本淹没普通差异比较的格式变化和键顺序变化被消除,因为比较前两份内容采用了相同的写法。

两个页面都没有任何网络功能——这一点值得知道:人们拿来比对的 JSON,太多时候是凭据还躺在里面的配置文件。

配置改动和 API 回归检查

比较预发布与生产配置时保留原件,把副本都设为两空格缩进并排序对象键。预发布放左、生产放右,不勾选忽略大小写或空白,检查端点、功能开关和上限。字符串里的空格、键的大小写可能有意义。确认两侧环境再下载补丁。

比较 API 改动前后响应也一样,使用相同请求输入,另行考虑时间戳和生成 ID。数组顺序保留,重新排序仍会显示差异。1 与 1.0、转义写法不同的字符串也可能不同。这里比较格式化后的文字,不检查架构,也不判断所有 JSON 值是否等价。JSON 标准把对象定义为无序,把数组定义为有序。

为什么生比 JSON 几乎全是噪音

JSON 不在乎空白,也不给键的顺序赋予意义。同一份文档可以是一行,也可以是四百行;键可以按敲下的顺序排,也可以按某个库吐出的顺序排——工具改写这两样从不打招呼。一边压缩了,一边铺开了;一边手工存的,一边出自按字母排序的序列化器:逐行比对看见的是两个不相干的文件。

两个最糟的情形足以说明问题。压缩过的文件是一行,于是和它比对得到一条巨大无比的变更行——正确,且无用。而内容相同、顺序不同的两个文件会比出个处处皆变,诚实的答案本该是“什么都没变”。

比较选项包含并排或行内视图、只显示变动行,以及忽略空白、大小写和空行的开关。
谨慎使用忽略开关。它们影响显示,但下载的补丁保留输入中的全部差异,包括换行符。

格式化器的规范形修好了什么

两个文件过同一个格式化器、用同样的设置,正是比对需要的:一份文档一种拼法。

一句诚实的但书:排序后的输出是键挪了位的文档。要是下游某个工具在乎键的顺序——在乎的不多,但存在——就把排序的副本当作被比对的东西,而不是原件的替身。

读结果,并带走它

比对把删掉的行标在左边、新增的行标在右边,变了的行里再把不同的词高亮出来:在规范形上,那通常就是从 false 挪到 true 的那一个值。没变的中段折叠成一个数字,两千行的配置改了三处,读起来就是三小段。

下载下来的是统一格式的补丁,一个 .patch——代码评审看得懂的格式。它描述的是规范形,而那通常正是评审想要的:只有改动,没有重排。

先格式化再比较,也能让 YAML 或 XML 更容易审查,但它们的空白和转换规则不同于 JSON。如果只需要调整排版,就保留原语言。比较工具的忽略开关影响视图,补丁仍比较实际输入字符串。这里输入的是格式化后的副本,因此补丁不是针对未改动原件生成的。

同一份 JSON 配置的两个版本并排显示,改动过的行都有标记:版本号、重试次数、新增的开关和新增的地区。
四处真正的差异,别的什么也没报。读是容易的那一半,活是上面那些设置干的。

如果你每周都做这件事

格式化两次、粘贴两次:步骤住在两个页面上,因为每页只干一件事,而且各自都能证明你贴的东西哪儿也没去。但两个都是开源的:MIT 许可证,零依赖的 ES 模块——格式化器的解析器保住键序和数位,比对是 Myers 算法——各配一份讲明白它的 README。

要是这已是你每天的一部分,把编码智能体指向代码仓库,请它做一页两个框、边比对边规范化的页面:parseJson、printJson 和 compareText 只隔三个 import。这些模块写出来就是给人读的,把它们搬走,正是这份许可证存在的目的。