谈ng-zorro-antd组件库的构建思维

为什么要使用组件库?如果不用会产生什么问题?

假设我们不用组件库,一个系统有上百个页面,每个之间页面都是没有依赖的,这每个页面都有自己的组件,每当新建一个页面并且有用到相似组件,这份组件就有可能被拷贝一份。组件就被分隔成了互不干扰的状态,这样做确实有好处,好处就是产品突然有了灵感说,这个页面的某某控件想要优化点东西和交互效果,那就可以做到不影响其他页面的组件以达到产品的需求。那么问题来了, 若其中一个页面其中组件发现了 bug,那么这份源组件及其他副本组件都存在隐患,都需要进行修复,这样的工作量无疑是繁琐且浪费精力的。

image.png

image2.png

用了组件库,带来什么好处?

就如上面所说,反之,其中一个好处就是减少迭代维护组件时的工作量,具体的说,就是当一个组件出现问题时,只需要修改一处即可。
npm 的推广理念不谋而合,可以在项目里通过 npm 管理实现了热更新,管理组件版本等。

怎么实现组件库

我们先思考,一个组件库的诞生,到底需要做些什么事情?
我大概整理以下构建思路仅供参考:

  1. 组件库的模式(单包/多包)
  2. 组件入库标准
  3. 组件的开发
  4. 组件库文档及组件文档在线例子
  5. 组件发布
  6. 组件迭代维护
    无论是二次开发还是原生开发,以上的流程是必不可少的(可能还要加上单元测试的流程)
    我们在使用一些 ui 框架时,是不是有一些疑问
  7. ui 框架的文档到底是怎么编写的?
  8. 组件的示例是怎么跑起来的?
  9. 这个组件库上的示例是否和我们从 npm 下载回来的保持一致?
  10. 组件库有多个版本,那对某个版本到底是怎么维护的?
    现在我们结合构建思路以 ng-zorro-antd 为例,一一展开以上思路探讨部分问题:
    下面谈到的组件文档,也统称为

该 ui 框架的文档到底是怎么编写的?

碰到问题的第一反应,大都是“到底是怎么回事”吧,那这个文档怎么编写呢,我先从总体说明;

  • 首先该组件库是以单包的形式构成(单包即指,所有的组件都集成一个包,以【组件库名/具体组件名】形式引入;多包即指组件以多个 npm 包分开发布,两者优缺点就不一一说明了)

image3.png

  • 组件和文档集成在一个项目,即整个 ui 使用文档,更新日志,组件使用文档等相关文档和组件代码放在一个项目里

  • 组件有他自己的示例 md,汇总每一个 md 组成属于该组件例子

  • 文档使用 md 格式规范编写,再由 md 转 html 技术生成页面,可使 md 文件以 html 直观展示在浏览器(md 转 html 的技术再后面文章会仔细介绍)
    文档以 md 形式编写而不直接用 html 形式编写的原因,从最直接的原因看,就是在 git 代码管理仓上有直观的文档,代码放在 git 仓库,这样的话以 md 的形式是最好的方法

组件的示例是怎么跑起来的?

你是否会有这样的疑问,组件在一个文档网站跑起来并且有相应代码显示,感觉到神奇,到底是怎么实现的。

  • 首先,要以什么框架为底层,以 ng-zorro-antd 为例,底层框架当然是 angular,当 md 等生成 html 时,通过 angluar/cli 启动该文档,就可以看到整个文档效果
  • 组件相应的例子代码 .ts,和相应的例子说明文档 .md,以及这个组件整体说明文档,组成一个组件完整文档

image4.png

  • 组件是服务于 angular,那么内部的组件包括二次开发的组件,必须按照 angular 的开发规范来,文档系统也并应该按 angular 的规范来,归根结底,文档系统底层的选择,无非就是看组件依不依赖于某个框架,当然若该组件无外部依赖,那么底层的选择可以自由发挥,可以原生开发。

组件库有多个版本,那对某个版本到底是怎么维护的?

一个版本发布,常用的大致可分为三个版本 major | minor | patch,那么组件库的发布也遵循这一规则。

  • 页面如何访问不同版本
    在文档页面选择不同版本达到看到不同版本的文档,我们先看看官网是怎么处理的:
    12 版本(左图), 11 版本(右图), 访问 12 版本的时候 11 版本的显示是 11.4.x,
    而当访问 11 版本的时候显示 11.4.2, 这是因为每个版本的页面当前的版本是最新版本,而当开发 12 版本的时候已经是 11 版本的最高版本,但是并不知道 11 版本后面会修复哪些内容,所以在 12 版本写死了 11.4.x , x 这个是会变动的
  • 根据上面的逻辑,我们可以推测出,此 git 代码如何管理,粗略画了以下流程,从图中可以看出,组件库的版本以 tag 的版本保持一致,那么文档页面的构建也应该与 tag 保持一致,当然并不是所有版本都必须有一个不同的页面,比如现有版本8.0.0, 8.1.0, 8.2.0,那是不是有三个版本的页面?其实不然,按以大版本为主,小版本为辅的原则。也就是应该要按 major | minor 版本变动为原则,在根据实际的情况考虑构建不同版本页面

image7.png

  • 当然,这种访问不同页面的方式有很多种,我自己琢磨出其中一种,以 nginx,jekins,git 工具 1.根据不同 tag 构建到不同服务器目录,以访问不同目录达到访问不同页面

jekins 构建目录:
master/v7.x
tag:8.0.0/7.0.0
nginx:

1
2
3
4
5
6
7
8
9
10
location / {
alias xxxxx/dist/master;
index index.html index.html;
allow all;
}
location /version/7.x {
alias xxxxx/dist/v7.x/;
index index.html index.html;
allow all;
}

文档的最新访问地址 127.0.0.1:8080
7 版本的访问即 127.0.0.1:8080/version/7.x

组件库上的示例是否和我们从 npm 下载回来的保持一致?

答案是必须要一致的,从上面谈到文档系统,是由组件库和使用文档构成,那结果从原则上必然是保持一致的。当然,不排除有人开发完之后脱离了发布组件步骤就发布了文档。这种情况应当属于团队规范范畴就不探讨了

总结

在浏览了 ng-zorro-antd 的文档生成系统之后,受到了启发颇大,从整个的设计思想值得我们去借鉴。从 8 版本之后,ng-zorro-antd的团队就引入 gulp 的一个构建工具,为什么引入这个工具也是值得探讨的,后面也会陆续发表跟这篇文章相关的文章,比如《md 生成 html 技术》《gulp 的使用及与其他打包工具的区别》 [笑脸]。

作者

wuxunyu

发布于

2021-10-24

更新于

2022-07-04

许可协议