JSON 工具箱

JSON 解析与处理库选型对照

结论:原生 API 最快,容错解析带偏移量,路径查询与补丁各管一段。选型看三件事:错误定位、是否破坏原文、边界是否明确。

进阶约 11 分钟发布于 2026-10-30更新于 2026-10-30
JSON 解析与处理库选型对照封面

结论:先按用途分四类再看实现——只读值用原生 JSON.parse,需要偏移量或保留原文格式用 jsonc-parser,查询与补丁库各自按需引入;体积大的库按页面动态导入,长期不维护的库直接排除。

每个库都宣称自己「快、小、全」。真正区分它们的是出错时能告诉你多少信息。

一、按用途分四类

类别 代表库 解决什么
标准解析 JSON.parse / JSON.stringify 语法 ↔ 对象,速度优先
容错解析 + 编辑 jsonc-parser、json5 带注释的输入、精确到偏移量的错误、保留格式的修改
查询 jsonpath-plus、jsonpath 按表达式筛选节点
变更 fast-json-patch、immer 生成/应用补丁,不可变更新

先确定自己在哪一类,再比较具体实现,否则很容易拿查询库去干解析的活。

二、横向对照

库 错误定位 容错(注释/尾逗号) 能否保留原文格式 适用场景
JSON.parse 只有消息与位置(引擎相关) ✗ ✗ 默认解析、接口数据
jsonc-parser 精确 offset + 错误码 ✓ ✓(modify + applyEdits) 编辑器、配置文件
json5 行列信息 ✓(更宽松) ✗ 读取 JSON5 配置
jsonlint 行列信息 ✗ ✗ 仅作参考,维护不活跃
jsonpath-plus 表达式语法错误 — — 按表达式查询
fast-json-patch 操作级错误 — — 补丁生成与应用
lz-string — — — 把 JSON 压缩进 URL

JSON.parse 的错误信息在不同引擎差异很大。V8 会给出类似 Unexpected token } in JSON at position 42 的提示,但位置是否准确取决于引擎版本; jsonc-parser 则稳定返回结构化的 { error, offset, length },适合做编辑器标记。

三、四个关键决策点

3.1 需不需要偏移量

做编辑器、要做「点错误跳转到对应行」就必须有 offset。判断方法很简单: 如果你的错误提示只能打印「JSON 格式错误」,用户就得自己找半天。

import { parse, printParseErrorCode } from 'jsonc-parser';

const errors: Array<{ error: number; offset: number; length: number }> = [];
parse(text, errors, { allowTrailingComma: true, disallowComments: false });

if (errors.length > 0) {
  const firstError = errors[0];
  console.error(`${printParseErrorCode(firstError.error)} at offset ${firstError.offset}`);
}

3.2 要不要保留原文

只想读值 → 任何解析器都行。 要「改一个字段、其余原样保留」→ 必须用编辑式 API,不能用「解析 → 改对象 → 序列化」。

后者会丢掉:注释、键顺序(部分实现)、缩进风格、数字字面量写法(1e3 变 1000)、转义形式(\u4e2d 变中文)。

3.3 边界行为是否明确

选库前查三件事的文档:

  1. 重复键怎么处理(取最后一个 / 报错);
  2. 大整数是否丢精度(多数 JS 库会,因为都走 Number);
  3. BOM、注释、尾逗号的支持范围。

没有文档说明的,就写个小样例实测。这比读 README 更可靠。

3.4 维护状态

JSON 库的风险不在功能缺失,而在长期不维护:安全补丁(原型污染、ReDoS)不会有人发。

四、其他语言的对照

语言 标准库 / 主流库 关键差异
JavaScript JSON.parse 数字一律双精度
TypeScript 同上 + jsonc-parser / zod 类型只在编译期
Go encoding/json 默认 float64,需 UseNumber() 保精度;json.RawMessage 延迟解析
Java Jackson / Gson / Moshi Jackson 需注意默认类型开启的风险
Python json / orjson parse_float=Decimal 保精度;orjson 更快但不支持所有类型
Rust serde_json 强类型反序列化;arbitrary_precision 特性保精度
C++ simdjson / RapidJSON simdjson 面向解析吞吐,RapidJSON 更通用

跨语言交换时,最容易踩的还是数字精度与时间格式,库的选择只能缓解不能消除。

五、典型组合方案

方案 1:工具站(浏览器端)

解析与错误定位:jsonc-parser
编辑器:CodeMirror 6 + @codemirror/lang-json
查询:jsonpath-plus
补丁:fast-json-patch
分享链接:lz-string

这套组合的特点是全在本地跑,不上传数据,符合工具类站点的隐私预期。

方案 2:服务端接口网关

校验:Ajv(schema 编译一次,复用)
解析:原生 JSON.parse(配合 body 大小限制)
大字段延迟解析:保留原始字符串,用时再 parse

网关层不要引入查询/补丁库做业务逻辑,那是业务层的事。

方案 3:CLI 与脚本

取字段:jq
格式转换:yq / dasel
交互浏览:jless
批量校验:ajv-cli

六、体积与性能的实际影响

  • jsonc-parser 体积很小,适合进主包;
  • json5 比 jsonc-parser 略大,因为要支持更多语法;
  • jsonpath-plus 包含表达式求值,体积明显更大,应随页面懒加载;
  • fast-json-patch 体积中等,只有对比功能时才需要。

优化手段很直接:按页面动态导入,别把它们塞进首屏 chunk。

const { JSONPath } = await import('jsonpath-plus');

七、检查清单

  • [ ] 按用途选库,不用查询库做解析;
  • [ ] 需要精确错误定位时用 jsonc-parser;
  • [ ] 需要保留注释与格式时用编辑式 API;
  • [ ] 实测重复键、大整数、BOM 三个边界行为;
  • [ ] 关注库的维护状态与安全通告;
  • [ ] 大体积库按需动态导入。

常见问题

如何按项目规模选择 JSON 库?

小到只读接口数据的工具,用原生 JSON.parse 就够;需要编辑器式错误定位或保留原文格式的中型项目,选 jsonc-parser;服务端网关只做校验与解析,查询和补丁库留给业务层;CLI 与脚本直接用 jq、yq、ajv-cli。按用途分类之后再比较具体实现,能避免拿查询库去干解析的活。

为什么维护状态比功能多寡更值得关注?

JSON 库真正的风险不在功能缺失,而在长期不维护:原型污染、ReDoS 这类安全补丁不会有人发。功能再全,只要维护停摆,出问题时只能自己打补丁。选型时把维护状态与安全通告当成硬指标,比对照功能表更有效。

能否用 JSON.parse 改字段并保留注释与缩进?

不能。「解析 → 改对象 → 序列化」会丢掉注释、键顺序、缩进风格、数字字面量写法(1e3 变 1000)和转义形式(\u4e2d 变中文)。要改一个字段、其余原样保留,必须用 jsonc-parser 的 modify 与 applyEdits 这类编辑式 API。