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

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

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

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

怎么实现组件库

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

  1. 组件库的模式(单包/多包)
  2. 组件入库标准
  3. 组件的开发
  4. 组件库文档及组件文档在线例子
  5. 组件发布
  6. 组件迭代维护

无论是二次开发还是原生开发,以上的流程是必不可少的(可能还要加上单元测试的流程)
我们在使用一些ui框架时,是不是有一些疑问

  1. 该ui框架的文档到底是怎么编写的?
  2. 组件的示例是怎么跑起来的?
  3. 这个组件库上的示例是否和我们从npm下载回来的保持一致?
  4. 组件库有多个版本,那对某个版本到底是怎么维护的?

现在我们结合构建思路以ng-zorro-antd为例,一一展开以上思路探讨部分问题:
下面谈到的组件文档,也统称为文档系统

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

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

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

image.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,以及这个组件整体说明文档,组成一个组件完整文档

image.png

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

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

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

  • 页面如何访问不同版本

在文档页面选择不同版本达到看到不同版本的文档,我们先看看官网是怎么处理的:
12版本(左图), 11版本(右图),好了,我相信你已经发现了点端倪,访问12版本的时候11版本的显示是这样的11.4.x,
而当访问11版本的时候显示11.4.2,而且没有了12.0.1的选项,这是因为每个版本的页面当前的版本是最新版本,而当开发12版本的时候11.4.2已经是11版本的最高版本,但是并不知道11版本后面会修复哪些内容,所以在12版本写死了11.4.x,这个x是会变动的
image.pngimage.png

  • 根据上面的逻辑,我们可以推测出,此git代码如何管理,粗略画了以下流程,从图中可以看出,组件库的版本以tag的版本保持一致,那么文档页面的构建也应该与tag保持一致,当然并不是所有版本都必须有一个不同的页面,比如现有版本8.0.0,8.1.0,8.2.0,那是不是有三个版本的页面?其实不然,按以大版本为主,小版本为辅的原则。也就是应该要按major | minor版本变动为原则,在根据实际的情况考虑构建不同版本页面

image.png

  • 当然,这种访问不同页面的方式有很多种,我自己琢磨出其中一种,以nginx,jekins,git工具

1.根据不同tag构建到不同服务器目录,以访问不同目录达到访问不同页面
jekins构建目录:master/v7.x
tag:8.0.0/7.0.0
nginx:

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

文档的最新访问地址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的使用及与其他打包工具的区别》 [笑脸]。