Json diff 定制化需求

3,963 阅读3分钟

需求背景

有一个比较 json 的需求,希望对比高亮不同的值,并给出对应的key值一个波动范围,比较不同的值,如果超出波动范围则进一步高亮并在后面给出对应的变化率。效果上有点像下图 diffchecker 提供的样式内容上再定制化。

image.png

下面调研了几种方案,并简单介绍它们的优劣和不同。

  • codemirror merge 插件
  • monaco-editor
  • json-editor
  • jsdiff 自渲染
  • jsdiff diff2html

codemirror

挺强大的一个编辑器内容,核心功能比较简单,但是提供了较多的api和插件实现功能。

codemirror.net/demo/merge.…

效果图:

image.png

需要搭配 diff-match-patch 这个 diff 包来使用。

monaco-editor

微软出品,诞生于 vscode ,开箱即用。

microsoft.github.io/monaco-edit…

image.png

json-editor

基于 Ace编辑器 开发,针对 json 提供了较多的功能。本身没有提供一个 diff 的功能,但是暴露了两个函数可以使用。onClassName() 接受 json path,配合 lodash 的 get() 可以拿到左右 json 的值进行对比,返回对应的行的 className 进行样式的控制。onValidate() 返回一个对象数组,对象内容为{Path,message},分别为有问题的 json path 位置以及错误信息内容,进行自定义的错误提示。

jsoneditoronline.org/#left=local…

踩坑说明: 这个是 jsoneditor 一个在线demo ,但是作者在 jsoneditor 多加了一些 diff 功能以及左右自适应宽度等功能,是通过其他库实现的,jsoneditor 本身不提供,看了一下,diff 功能是通过 diff-sequences 实现,但是本身还是通过 json path 定位,所以 diff 功能没有那么优秀。

github.com/josdejong/j…

image.png

补充

各编辑器 npm trends 对比

www.npmtrends.com/ace-code-ed…

选型对比: (主流js编辑器对比,codemirror VS monaco-editor VS Ace)

sq.sf.163.com/blog/articl…

jsdiff + 渲染 / jsdiff + diff2html

jsdiff:github.com/kpdecker/js…

jsdiff 是一个对比工具, 返回的是一个更改对象的列表,再通过下面的方案来渲染出对应组件内容。

渲染方案: juejin.cn/post/685512…

通过 jsdiff + 渲染 方案可以在渲染每一行内容的时候,提前获取到这一行的内容,识别对应 json 的 key 和 value 进行对比,判断左右 value 是否超过波动范围,进行进一步的自定义内容渲染。

缺陷: 只能获取到当前渲染行的 key、value,无法获取到 json 的层级关系,如果在多个层级里面存在多个相同的 key,并且对多个层级的相同 key 波动范围要求不同,则无法满足这个需求内容。

diff2html: diff2html.xyz/

渲染方案: image.png

diff2html 方案:

image.png

总结:

  • 以上方法对基础的展示 json 并对比结果功能都可以支持,主要是对一个波动范围进行区分比较困难。
  • 编辑器过于集成化,依赖有无暴露出来的自定义校验方法 (codemirror / monaco-editor 淘汰)
  • jsoneditor 提供 onValidate(),onClassName()方法供自定义渲染、校验,核心依赖于 json path,相比于其他方案的 diff 结果不是那么优秀(对比结果是一一对比出来的)。
  • 使用 jsdiff + 渲染方案 可以在渲染的时候读取对应的值来支持对波动范围的区分。

结论

要支持 json diff 且对波动范围有区分要求,可以通过下面两种方法实现。

  • jsoneditor -> onClassName() onValidate()
    • 优点:编辑器集成的功能更多,不用重复造轮子。
    • 缺点:对 json diff 的支持并不好。
  • jsdiff -> 自渲染时读取对应的值进行对比,控制样式内容
    • 优点:依赖少,自定制化强,可以较好的控制样式内容。
    • 缺点:支持的功能比较少,相比于其他成熟的编辑器内容,搜索,折叠功能都有所缺失,自己实现的工作量大,无法确定当前判断行的 json 层级位置,所以出现多层级的相同 key 判断时无法满足需求内容。