背景
笔者之前为了为日常开发提效,做了低代码相关的调研,并输出了【低代码漫谈】系列。最大的收获就是从 amis 和 lowcode-engine 偷师,尤其是后者,让笔者对「协议先行」有了更深入的认识。只要协议统一了,就可以屏蔽掉底层框架、组件库甚至是编程语言的差异,更方便开发一些工具来提效。
但是,虽然 lowcode-engine 已经输出了一套很全面的协议,但是还没有完全成熟,比如对于 Vue 系的支持还不够友好(详见《lowcode-engine - Vue Renderer 尝试》)。而笔者的诉求是可以适配 React、Vue2、Vue3 的项目,所以暂时还无法较低成本的享受现有工具的成果。
不过协议先行的思想给了笔者很大的启发,最近也一直在思考这件事情。笔者最开始的诉求是提高表单和列表的开发效率(因为主要是中后台项目),无法统一全部的协议,但是至少可以先统一组件层面的协议吧。说得再具体点就是输出一套统一的表单和列表组件的 API,然后各 UI 组件库按照该协议实现组件。当 API 协议统一后,结合配置化开发可以从多方面提高研发效率。
配置化开发
所谓配置化开发,即将所有的 props 提取成对象,然后把这个对象传给封装好的组件即可,如下伪代码:
// config
const formProps = {
onSubmit() {},
items: [{
label: "Name",
componentName: "Input",
bind: state.name
}, {
label: "Age",
componentName: "InputNumber",
bind: state.age
}],
// other code
};
// jsx usage
return <FormRender {...formProps} />
// Vue Template usage
<template>
<FormRender v-bind="formProps" />
</template>
这样做可以带来以下好处:
- 使用层面几乎完全统一。不管项目用的是什么框架,什么 UI 组件库,配置代码是完全相同的。这点尤其有利于紧急项目,需要人力临时支援的情况,可以最大限度的降低切换成本;
- 业务逻辑与组件完全解耦。这样就可以把配置(本质是业务逻辑)交给新手来写,组件封装交给老手来写。一是不同梯度人才的有效利用。二是可以让组件开发更聚焦,质量更好,也可以最大程度的实现组件复用。这两者相当于变相提高了团队的效率;
- 方便辅助工具的开发。因为配置是语言无关的,所以可以很方便的开发一些提效工具,包括但不限于代码片段、VS Code 插件、脚本、甚至可以直接利用现有低代码工具;
- 有利于项目的技术迭代。这属于第 2 点的延伸,由于项目当中绝大多数都是业务逻辑,当其与组件解耦时,这就意味着替换组件、组件升级甚至是整个项目技术升级的范围也就缩小了,而且更纯粹了。如果是升级一个 Input 组件,也许只是分分钟的事;
凡事都是两面的,所以配置化也会存在一些风险:
- 协议是否合理。合理具有几层含义,一是能够覆盖所有场景,一定要保留自定义能力。二是易用性要好,心智负担不能太重。三是学习成本不能太高,最好与业内应用比较广泛的协议尽量贴近。说实话,这很有难度,很考验设计者的水平;
- 如何顺利落地。我们的根本目标是提效,协议制定之后,还要封装组件,小范围实验调试,组织大范围推广、学习,修改现有项目代码,建立组件共享机制等一串连锁的事情要推进和设计。这其中只要有一个环节没有做好,那大概率会出现不上不下很尴尬的局面。甚至如果新老代码混掺,那真不好说是否能够提效;
不管怎样,理论上这个思路还是可以提高研发效率的,而且如果这个思路跑通了,后续还可以进行列表组件、Layout 组件、路由组件、上下文组件等的配置化改造,终极目标就是整个项目的绝大多数逻辑都可以通过配置化实现,那么就真的离低代码只有一线之隔了。先不扩展太多,还是先解决 Form 组件的协议问题吧。
分析调研
状态管理是表单组件最核心最复杂的部分,formilyjs 的文档列出了市面上主流的几个表单状态管理库,我们来比较一下(数据截止至 2022.05.24):
formik | react-hook-form | redux-form | react-jsonschema-form | formily | react-final-form | |
---|---|---|---|---|---|---|
介绍 | Build forms in React, without the tears ! formik.org | React Hooks for form state management and validation (Web + React Native) react-hook-form.com | A Higher Order Component using react-redux to keep form state in a Redux store redux-form.com | A React component for building Web forms from JSON Schema. rjsf-team.github.io/react-jsons… | Alibaba Group Unified Form Solution -- Support React/ReactNative/Vue2/Vue3 formilyjs.org/ | High performance subscription-based form state management for React final-form.org/react |
GitHub | 30.4k stars 242 watching 2.5k forks | 28.3k stars 172 watching 1.4k forks | 12.6k stars 176 watching 1.7k forks | 11.5k stars 169 watching 1.9k forks | 7.7k stars 145 watching 1.1k forks | 6.9k stars 84 watching 471 forks |
Npm | Weekly Downloads 1,999,893 Unpacked Size 580 kB Last publish a year ago | Weekly Downloads 2,028,913 Unpacked Size 783 kB Last publish 3 days ago | Weekly Downloads 391,870 Unpacked Size 1.45 MB Last publish 6 months ago | Weekly Downloads 154,810 Unpacked Size 3.46 MB Last publish 18 days ago | Weekly Downloads 5,668 Unpacked Size 1.49 MB Last publish 13 days ago | Weekly Downloads 464,430 Unpacked Size 191 kB Last publish a month ago |
备注 | Npm 数据为: @rjsf/core | Npm 数据为: @formily/core | Npm 数据为: final-form |
优先参考下载量来看,毫无疑问 formik 和 react-hook-form 是妥妥的第一梯队,优势非常明显,下载数高了一个数量级。而且后者不管是 stars 还是下载数增加的都很迅速,相信超过 formik 只是时间问题。
处于第二梯队的是 final-form 和 redux-form,前者由于是 react-final-form 的底层,虽然 stars 不是很高,但是下载量着实是不少,而且是纯 js 实现的,框架无关。至于后者,formik 文档开篇就聊了其局限性。所以如果深入研究的话,final-form 由于其框架无关性还具有一定的研究意义,后者暂时就不投入精力深入研究了。
处于第三梯队的是 rjsf 和 formily,其实二者已经不单纯是表单状态管理工具了,同时集成了 UI 方面的逻辑在,算是一套完整的表单配置化解决方案。也正因如此,相较前几个框架,它们的适用范围更窄,数据低一些也就不奇怪了。由于笔者目前是沿着【低代码漫谈】中的思路来研究的,所以二者自带的 UI 解决方案与笔者目前的方案存在些许冲突,所以暂时放弃对二者的深入调研。
总结
- formik 作为「老牌强者」必然要进行一番深入研究;
- react-hook-form 作为「新晋黑马」也肯定有其研究的价值;
- final-form 由于其框架无关性,也有研究一下的必要。
所以笔者后续会对三者进行更深一步的研究,而且会结合低代码的思路,从特殊的角度去分析,敬请期待。
“完美不在于无以复加,而在于无可删减,万事莫不如此。”
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away."——Antoine de Saint-Exupery