写点什么

漫谈 React 组件库开发(二):组件库最佳实践

  • 2020-03-11
  • 本文字数:2818 字

    阅读完需:约 9 分钟

漫谈 React 组件库开发(二):组件库最佳实践

一个系统拥有大量的业务场景和业务代码,相似的页面和代码层出不穷,如何管理和抽象这些相似的代码和模块,这肯定是诸多团队都会遇到的问题。不断的拷代码?还是抽象成 UI 组件或业务组件?显然后者更高效。


那么现在就面临一个选择:


一是选择 React 生态中已有的组件库,例如 antDesign、Material-UI 等比较成熟的组件库;


二是团队再开发一套属于自己的组件库。


有赞前端团队选择了后者,产出并开源了 Zent ,Zent 提供了一整套基础的 UI 组件以及常用的业务组件,目前我们有 45+ 组件,这些组件都已经在有赞的各类 PC 业务中广泛使用。本文我们就来聊一聊如何开发一套优秀的 React 组件库以及一套完整组件库的构成。

一、选择开源?还是自己造轮子?

React 大环境里面有很多优秀的 UI 组件库,国内比较有名的 antDesign,国外的 Material-UI,都是比较稳定和优秀的组件库。那么我们为什么还要自己去开发一套组件库呢?原因大致如下:


  • 有赞各个业务线 PC 产品有独立的设计规范,包括但不限于组件样式、交互模式。

  • 有赞微商城、零售、美业等 PC 产品的业务场景较为复杂,需要深度定制某些通用的组件,如 DesignSKU 组件。

  • 需要同时支撑有赞多个业务部门的 PC 产品。

  • 团队成员以开源的模式参与组件库的开发,期间会有很多互相的讨论、碰撞,本身也是对团队的锻炼过程。

二、组件库构成

构建一个完整的组件库需要考虑:


  • 组件设计思路

  • 组件代码规范

  • 组件开发流程

  • 组件测试

  • 组件维护(包括 PR / issue 管理、发包、文档)

1. 组件设计思路

组件是对一些具有相同业务场景和交互模式代码的抽象,组件库首先应该保证各个组件的视觉风格和交互规范保持一致, X 组件在 A 业务场景是一个交互,在 B 业务场景是另一个 UI 风格,这样就无法对 X 进行抽象,极大的增加了组件的构建成本。所以,设计组件之初,首先需要抽象和约定一套统一的视觉风格和交互规范。


其次,组件库的 props 定义需要具备足够的可扩展性,而且组件内部完全受控,保持组件具有统一的输入和输出,让我们来看一个 Button 的例子。


// Button is a react component of Zent<Button  type="primary"  className="customer-classname"  loading={true}  disabled={false}  size="large"  onClick={this.handleClick}>  {children}</Button>
复制代码


这是一个 Button 组件,我们定义了很多标记状态的 props,比如 type 表示 Button 的视觉风格,size 表示尺寸,disabled 禁用,loading 状态等,这些状态在组件内部都不会维护 state,所有的状态由传入的 props 来决定,自定义 className 方便我们做样式自定义,children 方便我们自定义 Button 的显示内容。


Button 甚至提供了 a标签的功能,只要在 Button 上传入 props:href。


// Button as <a><Button  type="primary"  className="customer-classname"  href="https://www.youzan.com"  target="_blank">  有赞首页</Button>
复制代码


我们需要做几个约定:


  1. 组件所有状态受控于 props

  2. 组件 children 支持自定义 Dom 结构

  3. 不要写死组件内部的 Dom 结构

2. 组件代码规范

有赞前端内部组件库,使用的是开源 lint 工具-- felint 。


felint 是一个集成了 eslint、stylelint、git hook 的前端代码检查工具。felint 为你的项目做以下三件事:


  • 初始化 eslint/stylelint 配置文件,无论是 react 项目、vue 项目、es5 还是 es6 都提供了针对性的配置方案

  • 安装 eslint/stylelint 及其依赖到当前项目的 node_modules 里

  • 挂载 git 钩子,在你提交代码时进行强制校验


具体使用可以参考官方 doc – felint 文档地址 。

3. 组件开发流程

约定好组件的设计思路和代码规范以后,接下来我们就可以参与开发组件了,组件库的基本开发流程,包括以下几点:


  • 组件初始化

  • 组件 Coding

  • 组件 Demo


Zent 里面有一个组件初始化命令: yarn new-component,这个命令完成了组件大部分初始化工作,包括自动创建组件需要的目录和模版代码,添加组件 js 和 css 代码。然后,我们就可以开始写组件代码,代码风格和规范严格按照 lint 的规范编写,如果不符合规范,是不能提交代码的。写完组件以后,需要写组件 Demo 并运行,方式是本地启动 server 来运行组件 Demo,这个可以组件作为组件的调试工具。

4. 组件测试

js 单元测试框架有很多,chai、jest、mocha、karma 等等,Zent 组件库使用的是 jest + enzyme 的组合,下面来看一个例子:


// Button UI testimport { mount } from 'enzyme';
describe('Button', () => { it('Button UI test', () => { const wrapper = mount(<Button>OK</Button>); expect(wrapper.hasClass('zent-btn')).toBe(true); expect(wrapper.text()).to.equal('OK'); });});
复制代码


使用 jest 做 UI 测试有局限性,只能测试基本的 dom 结构 和样式,一些逻辑交互无法测到,只能覆盖大部分的情况。 yarn test 用来执行测试脚本,测试结果会显示在终端。

5. 组件维护

组件日常维护占整个组件库生命周期的很大一部分,组件库做起来了以后,组件功能后续会不断迭代,也许是 bug fix,也可能是 new feature,这些组件的迭代我们通过 PR 和 issue 来管理,同时,我们需要管理好组件的 changelog。


总的来说,组件维护主要包括:PR / issue 的处理,发包和管理 changelog。


下面以 Zent 为例,来介绍一下 PR 规范。


PR 标题规则:[ bug fix / breaking change / new feature ] 组件名字:修改内容描述


  • 前面方括号用来区分 PR / issue 的类型:bug fix - 组件 bug 修复;breaking change - 不兼容的改动;new feature - 新功能

  • 修改内容尽可能言简意赅,总结 PR 的改动或者描述 issue

  • 描述请用中文

  • 组件名字请用英文,首字母大写


PR 用来生成 changelog,规范的 PR 有助于生成比较清晰的 changelog,一目了然,来看一下 Zent 的例子:


组件发包

组件发包只有拥有发包权限的人才能操作,Zent 是以组件库为单位发包的, yarn build 会将整个 Zent 的代码打包,使用命令 yarn publish 发包,在发包之前会跑组件测试,只有测试通过以后才能发包。

组件文档

一份好的 doc 是一个优秀组件库的标准,良好的文档能够提升组件库的整体品质和好感度,愿意花时间好好写 doc 的团队,那么他们产出的组件库应该也不会差到哪去,组件库文档维护也是组件库生命周期里重要的一环,有时候你甚至需要做到中英文双语 doc。


这里附上 Zent 组件库的 doc 地址:Zent。

三、小结

在本文中,我们从组件的设计思路、编码规范、开发流程、测试、日常维护这五个方面阐述了如何构建一个 React 组件库,并且以 Zent 为例讲述了有赞是如何做的,任何一个组件库都需要的经过这个生命周期,但我们需要思考的是:如何营造一个良好的组件库生态环境? 我们需要想办法让更多的人参与其中,共同作为组件库的维护者,选择开源是为了给 React 生态环境做输出,在前端组件化已经成为了既定事实的今天,我们不需要重复的造轮子,而是需要在组件化方面尝试新的突破,脱离前端技术的束缚,站在工程师的高度去抽象自己手头的代码。组件化这条路上,我们还有很多事情要做,Zent 只是一个开始。


2020-03-11 22:191515

评论

发布
暂无评论
发现更多内容

Android Handler源码浅析,一线互联网架构师筑基必备技能之Android篇

android 程序员 移动开发

OpenSearch 文档如何部署到 GitHub Page 中

HoneyMoose

Android jetpack最佳总结和实践,安卓面试题宝典app

android 程序员 移动开发

Android - singleTask启动模式详解(1),kotlinnative原理

android 程序员 移动开发

Android - 运行时权限一个工具类搞定,让人茅塞顿开

android 程序员 移动开发

Android 10手势导航的侧滑返回效果优化策略,2021最新Android大厂面试真题大全

android 程序员 移动开发

Android Gradle 常用配置,androidsdk环境配置

android 程序员 移动开发

Android Gradle 干货,sharedpreferences跨进程

android 程序员 移动开发

Android AOSP 6,flutter面试题

android 程序员 移动开发

OpenSearch 文档中文本地化

HoneyMoose

Android P 网络请求相关总结,flutter二维码扫描插件

android 程序员 移动开发

Android 9,flutter安装教程2019

android 程序员 移动开发

Android mvvm 之 LiveData 的原理,如何保证高可用

android 程序员 移动开发

Android MVP模式深入实践探索(一),移动开发工程师简历

android 程序员 移动开发

Android Studio 3,2021Android面试真题精选干货整理

android 程序员 移动开发

Android Studio自定义模板实现一键创建MVP结构,已拿到offer

android 程序员 移动开发

Android - singleTask启动模式详解,腾讯Android面试

android 程序员 移动开发

Android - 更安全地保存静态密钥,android三种开发模式

android 程序员 移动开发

Android 11 中的存储机制更新,android项目开发实战入门光盘文件

android 程序员 移动开发

Android 11适配指南之系统相机拍照、打开相册,Android开发两年

android 程序员 移动开发

Android Matrix矩阵,一个Android程序员的面试心得

android 程序员 移动开发

Android - AndroidStudio的下载、安装与配置,android开发艺术探索下载

android 程序员 移动开发

Android Protobuf应用及原理,android输入法开发软键盘切换

android 程序员 移动开发

Activity显示界面——说说View的那些理不清的关系,移动端h5页面适配

android 程序员 移动开发

Android Gradle 学习笔记整理,阿里Android面试必问

android 程序员 移动开发

Android - 开发常用工具类Utils,真的已经讲烂了

android 程序员 移动开发

Android JPEG 压缩那些事,深入解析Android-AutoLayout

android 程序员 移动开发

Android NDK 开发之 CMake 必知必会,程序员必须要了解的知识点

android 程序员 移动开发

Android AutoService 组件化,android完整项目源码

android 程序员 移动开发

Android BLE基础框架全新改版,android音视频开发面试题

android 程序员 移动开发

Android Manifest功能与权限描述大全,阿里大牛整理

android 程序员 移动开发

漫谈 React 组件库开发(二):组件库最佳实践_文化 & 方法_有赞技术_InfoQ精选文章