背景
- 公司内团队众多,公司层面缺乏组件库及组件开发规范,部分团队独立发布和维护自己的业务组件库,但移动端组件库不存在。
- 随着业务体量的增加,组件或模块复用场景越来越多,业务组件便是其中之一,但由于始终在单个项目维护,在跨项目需求中需要拷贝一份组件代码进行另行维护,这样往往造成很多类似的组件或模块,提高了维护成本和开发成本。
- 目前团队业务以移动端web为主,同时伴有微信公众号和微信小程序、OMS等,前端常用的技术栈是
Vue.js 2.x 全家桶+Vant+ElementUI等。
组件库基本需求
Vue技术栈- 支持按需加载
- 支持使用
TypeScript - API文档书写简单
- 支持自动生成API文档页面
- 组件示例书写简单
- 支持自动生成组件示例页面
- 支持复制代码
- 支持嵌入使用
codesandbox或codepen或stackblitz等在线编辑器
方案调研
市面主流UI组件库及搭建方案如下表格:
| 名称 | 前端框架 | 搭建方案 |
|---|---|---|
| ant design | react | @ant-design/tools + bisheng |
| element-ui | vue | 自行实现(markdown解析 + webpack) |
| vant | vue | @vant/cli |
| ant-design-vue | vue | @ant-design/tools |
| ant-design-mobile | react | @ant-design/tools + bisheng |
| mui | html | grunt |
方案选取
考虑以下因素后最终采用@vant/cli方案实现业务组件库。
- 团队成员大部分熟练
Vue.js,对React.js项目经验短缺; - 团队成员大部分使用
Vant及自行封装组件来完成业务UI需求; - 业务需求多,组件库搭建人力资源少;
@vant/cli脚手架集成了组件库的初始化配置,除未支持复制代码和未支持嵌入使用在线编辑器,其他均完美支持;
方案实现及状态
组件库已于2021年3月搭建及测试完毕并投入使用,组件库已拥有特性:
- 提供高质量业务组件和基础组件(共建方式);
- 性能极佳,组件平均体积很小;
- 完善的中文文档和示例(文档及示例已部署至内网);
- 支持
Vue 2.x和JSX语法糖; - 支持按需引入;
- 支持主题定制;
- 支持
TypeScript; - 结合
gitlab Webhooks+jenkins,支持自动化代码检测、测试、构建、部署;
代码库
方案实现关键点
@vant/cli提供了一些自定义命令,当启动dev或build-site命令时,其对应脚本会设置NODE_ENV并执行compileSite(),此函数在NODE_ENV=produciton下执行构建逻辑,否则执行开发调试逻辑。开发调试逻辑就是获取网站配置及webpack配置和可用端口后进行实例化webpack并启动webpack-dev-server。构建逻辑与开发调试逻辑稍微不同,获取配置时需要合并些mode、performance等配置。借助其自行封装的webpack plugin VantCliSitePlugin在beforeCompile(编译就绪前并在准备编译参数后)钩子被触发时进行生成组件库入口文件(暴露install方法、版本、组件)、组件库样式文件、网站示例相关配置、网站文档相关配置等,这些共同组成了@vant/cli/dist文件夹,该文件夹把本地网站配置和原始组件文档做了归纳整理,以便服务于桌面端文档渲染方案@vant/cli/site/desktop和移动端示例渲染方案@vant/cli/site/mobile,这两个方案也是网站构建的entry。
在webpack编译文件时,@vant/cli对markdown文件使用了自行封装的模块转换器@vant/markdown-loader及vue-loader,@vant/markdown-loader内部使用markdown-it将mawkdown内容转换输出为html,而模块转换器最终返回vue template 字符串以被vue-loader使用。结合其他插件和转换器,网站最终构建结果为index.html(桌面端文档)、mobile.html(移动端示例)、async_[name].[chunkhash:8].js、[name].[hash:8].js的静态资源文件夹(若配置了devtool,还会有.map文件。这里name是指webpack的入口名,hash:8是指将compilation.hash加盐后使用md5算法生成长度为8的十六进制字符串,简单理解就是基于webpack 构建内容生成的唯一标识;chunkhash:8则是值基于webpack chunk内容生成的唯一标识)。
@vant/cli在性能优化方面也做了很多尝试,如tree shaking、懒加载、限制webpack 入口文件及输出文件均不能大于5MB、使用cache-loader对babel-loader及vue-loader的结果缓存、将Vue.js作为外部资源引入等等。