从0到1打造高质量Web和移动端综合React UI组件库

887 阅读11分钟

背景故事 🖥

在绝大多数非B端复杂逻辑或者工具类的前端开发场景中,我们写下的大部分的代码都是在调用组件库来实现页面效果,而剩的一部分,是一些额外的特殊类库的使用或者是发送网络请求进行后端接口的交互,如此占比,甚至可以说这么一句话:

组件库,就是前端方向的其中一个天花板。

作者写这篇文章的时候,用业余时间探索组件库已经快2年半了,那些时候我和好多小伙伴一样,都不说如何开发一个组件库了,绝大多数组件的实现其实都是不清楚的,面试的时候介绍自己基本也只能说之前用过哪些组件库做过哪些业务,难以进一步深入组件细节讨论,而且那时对于开源项目的开发模式也是了解甚少的。

当时公司业务以C端为主,业务场景是海外信贷金融支付,有大量嵌套的H5页面,但那个时候有一个问题是,虽然看起来React生态如此繁荣,却找不到一个能很好驾驭C端复杂多变重设计重交互需求的移动端组件库,要么是移动端做得很好但是pc端做得很臭,要么是pc端做的很好移动端做得很臭,基本都只有建议凑合着用antd-mobile(当然,现在有一些优秀的组件库可以选择了)。说实话,还好最近他们大更新了一次,之前他们的这个组件库其实是非常难用的🤮,由于正在大版本更新,很长一段时间不再维护,使用体验完全比不过隔壁vant,这些原因促生了我们自己来做一个组件库的念头。

一开始也是得到了公司的支持并在大量的业务中测试使用和反馈迭代,当真正开始做的时候,你才发现小小的组件远比想象中的难,都不说代码量起来后的工程问题,一些组件内部实现细节都是很烧脑的。记得刚进入这行的时候,经常有看到一个面试题或者是一种文章,就是“手写一个轮播图”之类的,那时候我很不屑,初生牛犊不怕虎,我觉得不就是几个div嵌套,然后监听一下滑动事件嘛?有什么值得我研究的,但一旦开始真正自己做一整套组件的时候,各种问题会接踵而至,那时候你才感觉到,原来自己从前是那么的菜!不过现在很多刚入行的后浪比我们那时候厉害,确实像这种手撕细节都是手到擒来,感到非常佩服和有压力呀哈哈!说回来,当时我们还是顺利以此开发了好几个生产项目上线,但公司要恰饭嘛,随着大环境状况的不好,为了活下去承接的业务量的增加,慢慢也没时间继续迭代了。但毕竟每一个开源项目都像自己的孩子一样,虽然没有金主爸爸支持了,不说“望子成龙”,始终还是希望能把它“抚养长大”嘛哈哈。那么迭代发展到现在,我们不止移动端,更希望其可以覆盖所有的组件实现,让React开发,可以不再为了现有组件库功能的缺失而烦恼。

开始这个系列的文章,一是复盘和介绍一下目前组件库的进展和架构,二是希望吸引到有兴趣的小伙伴一起加入我们,后续会分享大多数常用的组件在本架构下的高质量实现的文章,帮助大家一起窥探组件的内核,实现世界级UI组件💪。

相关链接 🔗

Github仓库

贡献指南

前期探索 ✨

任何学习的开始都是模仿,在什么都不会的情况下,我们学(chao)习(xi)了主流的组件库架构方案,组件分类以及代码实现,当然在这期间,有很多的大佬发布自己的组件库或者组件实现的文章,我们也是悄悄的在背后学习研究并正向反馈到我们的组件库里。团队里的人都一致认为应该“三省吾身”,开发的时候时刻询问自己,我们目前做的组件库在业界水平里到底如何?做得不好的有哪些地方?该如何改进?我们的写法或者技术方案有过时的吗?等等问题。

所以,我们对比了大多数流行的组件库,无论是Vue、React还是Web Component,Svelte都有各自的优点值得借鉴,比如:

  • Vuetify 中对常用样式属性的缩写props,能极大地加速一些最常用样式的开发, 比如px='1em'会设置padding:0 1em,pa(padding all) 会设置padding:1em,ml会设置margin-left:'1em'等等。
  • Ionic 里的组件对原生移动端行为表现和样式的复原度非常高。
  • MuI 把组件库做到如此完善和庞大,工程实力可见一斑,并拆分多个不同模块,最近对组件进行headless的拆分也是我们一直认为非常有必要做的事情但是被人家先行了。
  • NextUI 基于stitches的令牌设计和主题系统非常全面,涵盖了各种样式类别,可以轻松定制所有的组件细节。
  • VantAntd 国人前端开源代表,借鉴意义很大,并有巨量业务沉淀和测试,让组件功能的丰富度,完善度都非常高,由此引伸出的 pro 版本系列业务组件和脚手架都是各个国内外项目在使用的。
  • Vuesax 拥有我们看来业界最潮流的组件样式设计,虽然非常小众,但里面对传统组件库样式和组件结构的质疑,重定义和动画设计给我们大量的信心和灵感。
  • TDesignNutUI 作为最近推出的大厂组件库,虽然有点强弩之末,但其跨越多端的特性,文档中特有的概览模块,以及特别是TDesign文档里对3D图标的应用让整个文档档次提升一大截。

除了对优秀前辈的学习以外,我们本着对技术求知求真,刨根问底的态度,专门求证和拜读了 IOSMaterial 设计指南,了解组件的命名,定义,了解组件的应用场景,了解组件在不同平台下该有的表现和反馈行为,反向去检查这些已经很优秀的组件库的组件是否存在误导?是否大家已经习以为常的一些组件似乎命名并不恰当?甚至开发迭代期间我们同一个组件也实现了好几个不同的css方案的版本,力求为了带来高质量的React组件。

设计系统 🎨

确实,似乎叫的上名的组件库都有一个设计系统,很可惜,我们一直没找到一个很好的方案...但,其实思路转过来,没有设计指南就代表就很low吗?不一定!不然就不会诞生 Vuesax 那样别具一格的设计~ 所以经过一段时间的研究后,我们发现一些前沿的设计网站诸如 DribbbleUplabs 之类的,上面有不少优秀的大胆创新的设计师分享自己的组件设计和看法,这些高质量的脑洞?远比目前的一些所谓设计系统更吸引着我们,我们对比和收集这些优秀的稍纵即逝的组件灵感,靠团队高质量的审美兜底,做出来的东西真的还行哦!当然我们也在积极推动在 Figma 中完成组件设计图的制作和存档。

技术架构 🔨

那么,在经过大量的准备工作和复盘,推倒,重来,迭代,最后最后,我们最终终于是找到了一个不错的架构:

  • 首先是组件库最重要的 css 样式方案,我们1年前就确定改为了emotion,css in js 方案可以提供最大的组件自由度,传统方案实现动态样式说实话,还有点点问题,jss 够轻量,但功能不够完善,styled-componentstyled()方式让我难以定制组件元素,stiches 的令牌设置很优秀,但还太年轻观望一下,诸如 vanllia-extract 之类优质的 css module 方案虽然已经足够好,可以非常优雅的实现大多数组件,但是在极端个别的C端样式需求上,css module 仍然会遇到一些技术或个人实现上的问题。
  • 项目管理上用到了成熟的 lerna 做 Monorepos,一开始项目只是个单独的仓库,但随着开始着手编写文档后,在进一步思考了组件的拆分和后续发展,加上确实需要实时的引入组件编写文档案例,最后还考虑到有可能也会进行 headless 和 hooks 的拆分,这样的场景下,引进了 lerna 重构项目结构。
  • 打包和开发方面,一开始就采用了轻量且靠谱的 rollup ,轻松生成umdesm模块并天然支持按需引入,一开始没做文档,有用 parcel 启动一个小服务来自己验证组件,但后面开始写文档了,就不再需要了,至于其他的打包方案呢,webpack 当时lib库模式还不太成熟,后面出的 vite 在其他项目上体验过确实不错,但内核似乎仍然是 rollup / esbuild,所以那对于我们来说就属于是可有可无的。
  • 文档正式启动后,上面也说了我们就取消了 parcel,采用 Docusaurus 开发,天然的 React MDX 支持,Algolia DocSearch 集成搜索,内置方便的 i18n 国际化和 TS 支持都是我们需要的,尝试过 dumi,看过一些文章,号称目前最适合组件库的文档方案,说实话,还需要完善,Storybook 原始ui实在是太丑,VitePress 不能很方便的支持React,但随着我们的深入使用,docusaurus有一个大坑,就是emotion和docusaurus的mdx集成有bug至今还没解决,哎,所以我们现在干脆不用现成方案,反正都是前端开发者,直接用 nextjs 完全重头写了一个。
  • 测试框架采用的 @testing-library/reactjest ,是比较主流的方案不容易踩坑,尝试过chai,我们不太喜欢。

组件进展 🚀

已完成,但还不够好正在完善的组件:

  • Button 按钮
  • Text 文字
  • Container 包裹器
  • Row 行
  • Col 列
  • Grid 单元格布局
  • Image 图片
  • Navbar 导航栏
  • Sidebar 侧边栏
  • Tabs 标签栏
  • Popover 浮动框
  • Dialog 对话框
  • Link 链接
  • Divider 分割线
  • Switch 切换
  • Segment 按钮切换组
  • Slider 滑块
  • Tag 标签
  • Noticebar 提示栏
  • Icon 图标
  • Breadcrumbs 面包屑导航
  • Badge 小红点
  • Card 卡片
  • Drawer 抽屉
  • Textarea 多行文本输入框
  • Progress 进度条
  • Upload
  • Toast 轻提示

以前完成过,但正在推倒重做的组件:

  • Collapse 折叠栏
  • Fab 浮动操作按钮
  • Tooltip 冒泡提示
  • CheckBox 复选框
  • Input 输入框
  • Indicator 指示器
  • Table 表格
  • Picker 选择器
  • PullRefresh 下拉刷新
  • InfiniteScroll 无限滚动
  • List 列表
  • Menu 菜单
  • Loading 加载
  • Radio 单选框
  • Steps 步骤条
  • Swiper 滑动布局
  • Skeleton 骨架加载

在所有组件完成开发后,将看情况拆分出 headdless 的部分或 hooks,精益求精,如果你对某些组件感兴趣,想学着试试自己实现,或者,对所有这些组件已经狠了解了,对我们有建议或者有全新组件想法的同学,我们正在等你!

发布和部署 📦

目前还没引入部署和发布版本号的流程,如果有很多大佬一起加入,或等到1.0版本规划的组件开发完成,再着手添加对应流程规范和文档的上线。

PR,ISSUE规范 📖

目前还没有提供pr和issue的模板但有提供pr和issue贡献指南以及commit规范。

最后 ❤️

之前有断断续续的兄弟主动参与迭代和提建议,大家都是有着自己全职工作的人,白天上班晚上肝,完全是对前端开发的兴趣和对自身的高追求驱动,非常感谢,也感觉到很幸运!欢迎更多有兴趣的小伙伴们加入我们!