本系列导航
- 上一篇:Birdor 风险复盘清单
- 下一篇:Birdor JWT Decoder 实现规格
- 返回目录:Birdor 商业计划书目录
本章关键词
JSON Formatter、实现规格、页面结构、状态机、错误类型、测试样例、本地执行、工具页模板。
适合阅读的人
- 准备实现 Birdor JSON Formatter 的工程师。
- 需要把 PRD 转成可验收产品规格的人。
- 想用 JSON Formatter 沉淀 Birdor 工具页标准的人。
本章摘要
JSON Formatter 是 Birdor 第一批基础工具中的样板工具。它的价值不只是格式化 JSON,而是验证工具页基础模式:本地执行、输入输出区域、操作按钮、错误提示、隐私说明、相关工具、FAQ、指标和后续 API 复用。
本文把 JSON Formatter PRD 和 首批工程 Issue 转成实现规格。实现时应优先保证正确性、稳定性和错误体验,AI schema 推断、批量处理、大文件 Worker 和 API 不进入第一版。
页面结构
JSON Formatter 页面建议分为六个区域:
| 区域 | 内容 | 要求 |
|---|---|---|
| Header | 标题、描述、隐私提示 | 说明本地处理,不上传输入 |
| Toolbar | Format、Minify、Validate、Sample、Clear | 按钮有 disabled/loading/success 状态 |
| Editor | 输入区、输出区、行号或基础高亮 | 桌面双栏,移动端上下排列 |
| Error Panel | 错误类型、行列、修复建议 | 解析失败时显示,不清空输入 |
| Utility | Copy、Download、Indent size | 操作完成有短反馈 |
| Content | FAQ、相关工具、API 预留 | 不干扰首屏任务 |
首屏必须能直接使用。SEO 内容和 FAQ 放在工具下方,不应把工具挤到折叠以下。
数据模型
页面状态建议包含:
| 字段 | 类型 | 说明 |
|---|---|---|
| input | string | 用户原始输入 |
| output | string | 格式化或压缩输出 |
| mode | format/minify/validate | 当前操作模式 |
| status | idle/dirty/success/error | 工具状态 |
| error | object/null | 解析错误信息 |
| indent | number | 缩进宽度,默认 2 |
| lastAction | string/null | 最近一次操作,用于反馈 |
error 对象建议包含:
| 字段 | 说明 |
|---|---|
| type | syntax、empty、too_large、unknown |
| message | 面向用户的错误说明 |
| line | 可选,错误行 |
| column | 可选,错误列 |
| suggestion | 可选,修复建议 |
状态机
状态流转建议如下:
| 当前状态 | 触发 | 下一个状态 | 说明 |
|---|---|---|---|
| idle | 用户输入 | dirty | 输入区出现内容 |
| dirty | Format 成功 | success | 输出格式化 JSON |
| dirty | Minify 成功 | success | 输出压缩 JSON |
| dirty | Validate 成功 | success | 展示 valid 状态 |
| dirty | 解析失败 | error | 展示错误,不清空输入 |
| success | Copy | success | 显示 copied 反馈 |
| success | Clear | idle | 清空输入输出 |
| error | 用户修改输入 | dirty | 清除旧错误或标记待重试 |
关键原则:任何失败都不能清空原始输入。用户输入是资产,工具必须保护它。
操作规则
Format:
- 输入为空时显示空输入提示。
- 输入合法时使用缩进输出。
- 输出区显示格式化结果。
- 更新 lastAction 为 format。
Minify:
- 输入合法时输出无多余空白的 JSON。
- 不改变字符串内部内容。
- 更新 lastAction 为 minify。
Validate:
- 输入合法时展示 valid 状态。
- 可输出格式化结果,也可只显示校验成功。
- 第一版建议同时输出格式化结果,方便用户继续复制。
Sample:
- 填入包含对象、数组、字符串、数字、布尔、null 的示例。
- 示例应简短,不超过首屏太多。
Clear:
- 清空 input、output、error。
- 状态回到 idle。
Copy:
- 优先复制 output。
- 如果 output 为空但 input 有内容,不自动复制 input,避免误导。
- 复制失败时显示浏览器权限提示。
Download:
- 下载 output 为
.json。 - output 为空时 disabled。
错误类型
第一版至少处理:
| 错误 | 判断 | 用户提示 |
|---|---|---|
| empty | 输入为空或仅空白 | 请粘贴 JSON 后再操作 |
| syntax | JSON.parse 失败 | JSON 语法错误,请检查逗号、引号或括号 |
| trailing_comma | 错误信息或简单规则命中 | JSON 不支持尾随逗号 |
| unclosed_string | 错误信息命中字符串未结束 | 字符串可能缺少结束引号 |
| unexpected_token | JSON.parse 返回 unexpected token | 存在非法字符或结构错误 |
| too_large | 超过前端处理阈值 | 输入过大,建议拆分或使用批量处理 |
| copy_failed | clipboard 失败 | 浏览器阻止复制,请手动选择文本 |
JavaScript 的 JSON.parse 错误文案在不同浏览器中可能不同,因此错误类型提取要容错。第一版可以先展示通用 message,再逐步增强行列定位。
测试样例
合法样例:
{"name":"Birdor","tools":["json","jwt"],"pro":false,"count":2}
预期:Format 输出带缩进 JSON,Minify 输出紧凑 JSON,Validate 成功。
嵌套样例:
{"user":{"id":1,"roles":["admin","api"]},"meta":{"active":true,"deletedAt":null}}
预期:嵌套结构缩进正确,数组和 null 保留。
缺少逗号:
{"name":"Birdor" "tools":["json"]}
预期:进入 error,提示语法错误,保留输入。
尾随逗号:
{"name":"Birdor",}
预期:提示 JSON 不支持尾随逗号。
空输入:
预期:提示请粘贴 JSON。
指标
第一版事件:
json_format_clickjson_minify_clickjson_validate_clickjson_parse_successjson_parse_errorjson_copy_clickjson_download_clickjson_related_tool_click
事件不记录原始 JSON。只记录长度、成功/失败、错误类型、操作类型即可。
验收标准
- 页面可访问,metadata 正确。
- 桌面和移动端可完成 format、minify、validate。
- 非法 JSON 不清空输入。
- 常见错误有可理解提示。
- Copy、Download、Sample、Clear 可用。
- 页面明确说明本地处理。
- 相关工具和 FAQ 可见。
- 事件埋点不记录敏感输入。
非目标
第一版不做:
- AI schema 推断。
- JSON5。
- JSON Schema validate。
- 大文件 Worker。
- 批量上传。
- 登录历史。
- API endpoint。
这些能力可以进入后续版本,但不应阻塞基础工具上线。
延伸阅读
- JSON Formatter PRD
- Birdor PRD 开发 Backlog
- Birdor 首批工程 Issue
- 工具页通用组件规格
- 第三十二章:前端工具页架构
- JSON Formatter 工具页 SEO 模板
大文件处理策略
JSON Formatter 的第一版不做大文件 Worker,但需要预留策略:
| 文件大小 | 处理方式 | 用户体验 |
|---|---|---|
| < 100KB | 主线程直接处理 | 即时响应 |
| 100KB - 1MB | Web Worker 处理 | 轻微延迟,有进度提示 |
| > 1MB | 提示"文件过大,建议使用批量处理" | 友好拒绝 |
| > 10MB | Pro 批量处理 / API | 引导付费 |
预留策略意味着:第一版的代码结构应该把格式化处理封装成一个独立函数,方便后续替换为 Worker 调用。
与 YAML/XML 的复用边界
JSON Formatter 完成后,YAML 和 XML 工具可以大量复用:
| 组件 | JSON | YAML | XML | 复用度 |
|---|---|---|---|---|
| 页面布局 (ToolLayout) | 是 | 是 | 是 | 100% |
| 代码编辑器 (CodeEditor) | 是 | 是 | 是 | 100% |
| 操作按钮 (ActionBar) | 是 | 是 | 是 | 100% |
| 错误面板 (ErrorPanel) | 是 | 是 | 是 | 80% |
| 格式化逻辑 | JSON.parse | yaml.parse | xml2js | 0% |
| 输出展示 | 缩进 JSON | 缩进 YAML | 缩进 XML | 60% |
| 验证逻辑 | JSON.parse | yaml.validate | xml.validate | 0% |
复用重点是"壳"(布局、编辑器、按钮、错误面板),不是"核"(解析逻辑)。
可访问性细节
JSON Formatter 的可访问性要求:
| 要求 | 实现 |
|---|---|
| 键盘导航 | Tab 顺序:输入区 -> 操作按钮 -> 输出区 -> 复制/下载 |
| 屏幕阅读器 | 操作按钮有 aria-label,如"格式化 JSON" |
| 错误通知 | 解析错误时,aria-live=“polite” 朗读错误信息 |
| 焦点管理 | 示例加载后焦点移至输入区;格式化成功后焦点移至输出区 |
| 颜色不依赖 | 错误不仅用红色,也用图标和文字说明 |
错误恢复增强
第一版错误提示是基础,后续可以增强:
| 增强 | 实现 | 优先级 |
|---|---|---|
| 行列定位 | 解析错误时计算行列号 | P1 |
| 错误高亮 | 在输入区标记错误位置背景 | P1 |
| 自动修复建议 | “是否自动移除尾随逗号?” | P2 |
| AI 修复 | 点击"用 AI 修复"自动纠正 | P2 |
| 历史对比 | 显示上次成功输入与当前差异 | P3 |
测试覆盖建议
第一版的测试不需要全覆盖,但关键路径必须有测试:
| 测试类型 | 覆盖范围 | 工具 |
|---|---|---|
| 单元测试 | format/minify/validate 函数 | Vitest |
| 集成测试 | 输入 -> 格式化 -> 输出 | Vitest + React Testing Library |
| E2E 测试 | 页面完整流程(桌面+移动) | Playwright |
| 性能测试 | 大输入(10KB/100KB/1MB) | 自定义 |
| 可访问性测试 | 键盘导航、aria 标签 | axe-core / Playwright |
FAQ 补充
Q: JSON Formatter 是否需要支持 JSON5?
第一版不需要。JSON5 是扩展格式,用户基数远小于标准 JSON。如果后续用户反馈中频繁出现 JSON5 需求,可以作为 Pro 功能或独立工具添加。标准 JSON Formatter 应严格遵循 RFC 8259。
Q: 格式化后的 JSON 应该按字母排序吗?
不应该。JSON 对象的键顺序在 ES2015+ 中是有意义的(按插入顺序)。自动重排序可能破坏用户预期的字段排列。如果需要排序功能,作为独立的"Sort JSON"工具提供,不要在格式化中默认排序。
Q: 输入框应该支持哪些编码?
第一版假设输入是 UTF-8。如果遇到其他编码(如 GBK),应提示"检测到非 UTF-8 编码,请转换为 UTF-8 后重试"。自动编码检测会增加复杂度和体积,不建议第一版加入。
Q: 格式化输出是否应该在 URL 中可分享?
是的,这是高价值功能。可以在 URL query 中编码输入内容(或短ID引用服务端存储),用户分享链接后接收方能看到相同内容。但要注意隐私:如果包含敏感数据,应使用私密模式(不存储在可分享的 URL 中)。
Q: JSON Formatter 是否适合作为 AI 工具的训练示例?
不适合。JSON Formatter 的输出是确定性的,没有需要"智能"判断的空间。AI 的价值在于理解 JSON 的语义(如"这个 JSON 代表什么数据结构"、“如何优化这个 schema”),这些功能可以作为独立的 AI JSON Assistant 工具,不应该污染基础的 JSON Formatter。
JSON Formatter 在 CI/CD 中的集成场景
虽然 JSON Formatter 主要是一个前端网页工具,但它的格式化逻辑可以自然地延伸到 CI/CD 场景:
| 集成场景 | 触发时机 | 输出 | 工具 |
|---|---|---|---|
| 提交前格式化 | git pre-commit hook | 格式化后的 JSON | jq / ppjson |
| PR 检查 | GitHub Actions | 是否格式一致 | custom script |
| 构建时验证 | CI pipeline | 解析成功/失败 | JSON.parse |
| 发布时压缩 | release pipeline | minified JSON | custom build |
Birdor 的 API 版本(/v1/json/format)可以让团队把标准化格式化加入工作流,而不必在每台机器上安装 jq。
JSON 格式化性能基准
不同方案的格式化性能对比(测试数据:10MB JSON):
| 方案 | 耗时 | 内存 | 环境 | 备注 |
|---|---|---|---|---|
| JSON.stringify(JSON.parse(), null, 2) | 120ms | 200MB | Node.js | 最简单,但不是最稳妥 |
| JSON.stringify + 自定义 formatter | 150ms | 180MB | Node.js | 可控制空格和换行 |
| jq | 80ms | 50MB | CLI | 最快,需安装 |
| Prettier | 300ms | 300MB | Node.js | 功能最全 |
| Birdor API | < 500ms | 服务端 | HTTP | 适合 CI/CD 集成 |
前端工具的格式化因为数据量通常 < 100KB,性能差异可以忽略。关键是正确性和错误体验。
JSON Formatter 与 JSON Schema 的关联
JSON Formatter 和 JSON Schema 是互补关系:
| 需求 | JSON Formatter | JSON Schema Validator |
|---|---|---|
| 检查语法 | 是(parse) | 是(parse + schema) |
| 修复格式 | 是(缩进) | 否 |
| 验证结构 | 否 | 是 |
| 检查必填字段 | 否 | 是 |
| 类型检查 | 否 | 是 |
| 提供示例 | 否 | 可以(从 schema 生成) |
Birdor 可以在 JSON Formatter 页面底部添加一个"验证 Schema"入口,引导用户到 JSON Schema Validator 工具,形成工作流连接。
FAQ 补充(续)
Q: 是否应该在格式化时自动排序 JSON 键?
不推荐默认排序,但可以作为选项。默认排序会破坏用户预期的字段顺序(比如 API 文档中字段有逻辑顺序)。如果用户需要排序(比如为了 diff 对比),提供一个独立的"Sort Keys"按钮。
Q: JSON Formatter 如何处理循环引用?
标准 JSON 不支持循环引用。如果用户粘贴了一个被序列化了的循环引用对象(比如用 util.inspect 输出),JSON.parse 会失败,应提示"输入包含循环引用或非标准 JSON 结构"。不要用 eval() 或自定义解析器去处理循环引用,这会带来安全问题。
Q: 格式化输出是否支持折叠/展开?
建议作为默认视图的一部分。可以折叠数组和对象,方便查看大型 JSON 的顶层结构。但如果折叠/展开的实现会增加大量 JS 体积,可以放到第二版。第一版至少提供文本输出。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。