功能要求
能力支撑:
- JSON 展示
- JSON 编辑(希望能直接编辑代码)
- JSON lint
case:
- JSON 展示能保留数字的精度
- 提供内置工具,保留数字的精度
- 支持传入 JSON 字符串
- 对嵌套引号能正常解析
特点:
- 支持在 react 项目中使用
工具对比
pkg | 功能是否满足 | star(截止0704) | GitHub地址 | 官方示例 |
---|---|---|---|---|
react-json-editor-ajrm | 不满足 case1、case2(case2 分析:juejin.cn/post/738535...) | 355 | github.com/AndrewRedic... | 代码:github.com/AndrewRedic... |
jsoneditor | 不满足 case1 | 11.3k | github.com/josdejong/j... | 代码:github.com/josdejong/j... |
jsoneditor-react(react wrapper implementation for josdejong/jsoneditor) | 不满足 case1 | 262 | github.com/vankop/json... | - |
json-editor | 功能不合适 | 5.8k | github.com/jdorn/json-... | 在线:rawgit.com/jdorn/json-... |
react-json-view | 功能不合适(不满足 能力2、case1) | 3.4k | github.com/mac-s-g/rea... | 在线:mac-s-g.github.io/react-json-... |
react-json-editor | 功能不合适 | 225 | github.com/ismaelga/re... | ismaelga.github.io/react-json-... |
json-rule-editor | 功能不合适 | 351 | github.com/vinzdevelop... | 图示:vinzdeveloper.github.io/json-rule-e... |
codemirror | 满足 | 5.4k | github.com/codemirror/... | v5 在线:codemirror.net/5/demo/v6 介绍:codemirror.net/examples/ |
@uiw/react-codemirror(codemirror6 component for React) | 满足 | 1.5k | github.com/uiwjs/react... | 在线:uiwjs.github.io/react-codem... |
codemirror vs @uiw/react-codemirror
对于满足要求的工具,优缺点说明
-
codemirror
-
优点:文档完善、配置丰富
-
缺点:需要自行封装 React 组件
-
-
@uiw/react-codemirror
-
优点:@uiw/react-codemirror 基于 codemirror,提供 React 组件
-
缺点:暴露的配置并不完整(相对于 codemirror 来说)
-
工具选择与使用
综合功能和易用性考虑,尝试采用 @uiw/react-codemirror 作为 JSON editor 实现的依赖包。
@uiw/react-codemirror 使用示例
效果展示:
JSON lint 错误示例:
代码示例:
tsx
import { json, jsonParseLinter } from '@codemirror/lang-json'
import ReactCodeMirror from '@uiw/react-codemirror'
import beautify from 'js-beautify'
import { linter } from "@codemirror/lint"
const jsonString = '{"type":"team","test":{"testPage":"tools/testing/run-tests.htm","enabled":true},"search":{"excludeFolders":[".git","node_modules","tools/bin","tools/counts","tools/testing/chutzpah","server.net"]},"languages":{"vs.languages.typescript":{"validationSettings":[],"allowMultipleWorkers":true}}}'
export const ReactCodeMirrorDemo = (props) => {
return (
<ReactCodeMirror
value={beautify(jsonString) || ''}
width="100%"
height='100%'
minHeight='100px'
maxHeight='400px'
style={{
overflow: 'auto'
}}
basicSetup={{
tabSize: 4
}}
extensions={[json(), linter(jsonParseLinter(), { autoPanel: true })]}
onChange={(value, viewUpdate) => {
try {
JSON.stringify(JSON.parse(value))
console.log("value", value)
} catch (error) {
//
}
}}
/>
)
}
版本要求说明
- @codemirror/lint 版本 6.0.0 不支持 autoPanel 的配置,版本 6.8.1 支持
- @uiw/react-codemirror 版本 4.22.2 支持 basicSetup={{ tabSize: 4 }} 配置
- @codemirror/lang-json 版本 6.0.1,@lezer/common 版本 1.0.1 报错,需要将 @lezer/common 版本升级到 1.2.1
问题记录
不能通过简单配置满足的需求:
-
希望 lint panel 放在头部
- 限制:codemirror 可以配置 top,@uiw/react-codemirror 不行
-
希望能支持代码格式化 format
- @uiw/react-codemirror 并没有 API 支持(或者提供什么轻量的插件支持也行)
- 可以通过
JSON.stringify(JSON.parse(value), null, '\t')
实现(这样处理会丢失数字的精度,不满足 case1) - 示例代码中通过引入 js-beautify 依赖包满足这个需求,但是 js-beautify 体积较大,引入成本过高
-
希望在满足 JSON lint 的条件下处理一些逻辑
- 如果可以通过 @codemirror/lint 暴露的API 得到 JSON lint 是否通过,就可以用这个 API 做判断
- 查看 @codemirror/lint 源码,发现 diagnosticCount,但计算的值并不符合预期
- 示例代码中为了满足这个需求临时使用 try...catch... 包裹
JSON.stringify(JSON.parse(value))
,目前还没找到更好的方案
- 如果可以通过 @codemirror/lint 暴露的API 得到 JSON lint 是否通过,就可以用这个 API 做判断