UI组件库-背景
tnpm:http://tnpm.oa.com/package/@tencent/kg-ui 文档:http://kgui.pages.oa.com/
为什么要开发组件库呢?
- 从业务角度:快速的业务迭代,组件有较多重复开发 //共性的地方应该复用
- 从设计角度:体验不一致;// 产品遵循一定规范性,保持产品一致性
- 从开发效率角度:效率低; // 需要快速响应业务开发
- 从可维护性角度:可维护性差;// 需要统一代码管理,不希望到处复制粘贴
UI组件库目标
- 支持hippy/h5
- 低耦合可扩展
- 项目快速接入
- 版本管理
- 文档清晰
- 支持换肤
组件库整体架构
组件设计-高内聚低耦合
组件设计是有一些方法论可以遵循,如内聚性和耦合性,内聚性就是组件封装的粒度,它主要是让组件整体稳定一些。
设计原则
- 单一原则
单一原则: 每个组件仅提供一个功能。
单一职责的组件的好处很明显,可以最大可能性地复用组件,但是这也带来一个问题 , 过度单一也可能会导致过度抽象,造成组件库的碎片化;比如在实现小红点,小红点基本上是结合文字和图片展示,如果我们单独把小红点提出来,会导致过于碎片化。
单一职责组件要建立在可复用的基础上,对于不可复用的单一职责组件我们仅作为独立组件的内部组件即可。
- 稳定性原则
比如我们有三个组件A、B、C,A不依赖于任何组件,X、Y、Z依赖于A。B不依赖于任何组件,M依赖于B,C是依赖于N,这个稳定性原则,最终的结果是:A>B>C;
原因是在实际情况中,如果你要给X、Y、Z增加一个功能,首先你可能不会改A的代码,因为这么多人用了A,改挂了怎么办?只有H依赖B,相对来说,你有可能修改B。这种情况下,A是相对更稳定的。也就是说,我们在依赖时,尽量去依赖很稳定的组件;
基于以上二点,我们设计和规划我们组件库的构成
组件是由一些基本的元素组成,文字、颜色、和图形等,通过这些基本的元素进行不同的组合,从而创造出统一且层次丰富的设计系统。
组件通用性
组件设计尽量灵活,除了丰富props,还支持用户自定义完成个性化定制需求。
我们在组件封装过程中发现,单纯的props和方法是无法完全满足用户个性化需求的;
为此,我们制定静态成员变量给到用户去自定义排列组合;
比如Modal弹层的实现:
代码语言:txt复制const { ModalContent, ModalDesc, ModalLink, ModalAction, ModalFeed } = Modal;
<Modal
isShow
imageUrl="https://y.gtimg.cn/music/common/upload/t_cm3_photo_publish/1830565.jpg"
title="标题"
closeType="white"
confirmText="确认"
btnType="primary"
>
<ModalContent>
<ModalLink>这是个链接</ModalLink>
<ModalDesc>这里是句补充说明的辅助文案。</ModalDesc>
<ModalFeed
imageUrl="https://y.gtimg.cn/music/common/upload/t_k_guild_comeptition_join_list/1799661.png"
title="主文案"
desc="辅助文案"
/>
</ModalContent>
</Modal>
总结:通用性设计其实是一定意义上放弃对 DOM 的掌控, 将 DOM 结构的决定权转移给开发者。组件只负责行为和最基本的 DOM 结构;
组件工程化
- 本地调试:支持web,hippy调试
- 组件依赖更新问题:接入多包管理lerna
一键安装依赖:很多模块都会依赖babel、eslint等模块,这些大多都是可以共用的, 我们可以通过lerna link convert命令,将它们自动放到根目录的package.json文件中去。
通过lerna bootstrap 命令安装依赖并将代码库进行npm link。
代码语言:txt复制 自动更新依赖:根据 git 信息,检查产生修改的组件;更新有过修改的组件的版本号,同时更新引用方组件的版本号;
代码语言:txt复制 支持独立版本管理
- 代码规范: 接入@tencent/kg-lint
提供git hook: husky
代码语言:txt复制 支持eslint(代码规范) prettier(风格统一) commitlint (提交规范) 团队默认config 代码规范eslint
代码语言:txt复制 提交规范commitlint
代码语言:txt复制 风格prettier
代码语言:txt复制 自动适配本地和CI环境,一键执行
- 代码质量:
接入TS:类型检查,代码提示,自动补全;减少更小的BUG
接入Jest:支持 DOM API, 断言库,快照, 覆盖率, 生成报告;collectCoverage 生成测试报告;
`
- 组件工程化-版本管理
目前我们支持了二种方式发包;
一种是合入master,自动发包;merge_requests 触发 Orange CI,检查编译是否通过;目标分支被合入 master 后,master 分支触发 Orange CI push hooks,发布版本;
版本号生产遵循conventionalcommits;
根据 git 信息,检查产生修改的组件;
更新有过修改的组件的版本号,同时更新引用方组件的版本号;
将 package.json 修改提交 git, 并以该版本号作为 commit 信息;
将所有有修改的组件发布至 npm 发布完成
fix: 类型 为 fix 的提交表示在代码库中修复了一个 bug,修改小版本号。
feat: 类型 为 feat 的提交表示在代码库中新增了一个功能,修改次版本号。
一种是分支发布,手动打beta版本; 分支发布不推荐;业务代码必须使用正式版本号的 package;使用commit-hash,可以有效避免冲突;
文档建设
react-styleguidist是基于JSDOC的一个可以帮助react项目快速构建项目文档的一个插件。 styleguide会默认为src/components/*/.js的js文件生成文档,styleguide读取了注解、组件Props 我们生成了组件文档,并且将propTypes的注解放到description中
组件扩展
es模块规范输出;es模块import 和 export 是确定的;
借鉴 antd 接入babel-plugin-import 默认支持基于 ES module 的 tree shaking,
- k歌项目接入babel-plugin-importimport { Modal } from “@tencent/kg-ui”;
- 手动引入(不使用以下插件也会有按需加载的效果)import Modal from "@tencent/kg-ui/lib/components/Modal/index";
成功展示
目前已经在全民k歌和轻缘APP全面接入
欢迎体验:
tnpm:http://tnpm.oa.com/package/@tencent/kg-ui
文档:http://kgui.pages.oa.com/