1.需求分析
丰富的 feature:丰富的组件,自定义主题,国际化。
文档 & demo:提供友好的文档和 demo,维护成本小,支持多语言。
安装 & 引入:支持 npm 方式和 cdn 方式,并支持按需引入。
工程化:开发,测试,构建,部署,持续集成。
丰富的 feature
丰富的组件
组件库最核心的还是组件,先来看一下 element-ui 组件的设计原则:一致、反馈、效率、可控。具体的解释在官网有,我就不多贴了,在 element-ui 开发团队背后,有一个强大的设计团队,这也得益于 element-ui 的创始人 sofish 在公司的话语权和地位,争取到这么好的资源。所以 element-ui 组件的外型、配色、交互都做的非常不错。
作为一个基础组件库,还有一个很重要的方面就是组件种类丰富。element-ui 官方目前有 55 个组件,分成了 6 大类,分别是基础组件、表单类组件、数据类组件、提示类组件、导航类组件和其它类型组件。这些丰富的基础组件能很好地满足大部分 PC 端 to B 业务开发需求。
开发这么多组件,需要大量的时间和精力,所以这里要非常感谢 element-ui 团队,为我们提供了这些基础组件,我们基于它们做二次开发,节约了非常多的时间。
element-ui 的组件源码在 packages 目录里维护,而并不在 src 目录中。这么做并不是为了要采用 monorepo,我也并没有找到 lerna 包管理工具,这么做的目的我猜测是为了让每个组件可以单独打包,支持按需引入。但实际上想达到这个目的也并不一定需要这么去组织维护代码,我更推荐把组件库中的组件代码放在 src/components 目录中维护,然后通过修改 webpack 配置脚本也可以做到每个组件单独打包以及支持按需引入,源码放在 src 目录总是更合理的。
自定义主题
element-ui 的一大特色是支持自定义主题,你可以使用在线主题编辑器,可以修改定制 Element 所有全局和组件的 Design Tokens,并可以方便地实时预览样式改变后的视觉。同时它还可以基于新的定制样式生成完整的样式文件包,供直接下载使用,那么它是如何做到这点的呢?
element-ui 组件的样式、公共样式都在 packages/theme-chalk 文件中,并且它是可以独立发布的。element-ui 组件样式中的颜色、字体、线条等等样式都是通过变量的方式引入的,在 packages/theme-chalk/src/common/var.scss 中我们可以看到这些变量的定义,这样就给做多主题提供了方便,因为我只要修改这些变量,就可以实现组件的主题改变。
了解了基本原理,做在线替换主题也并不是难事了,我并不会详细去讲在线定制主题前端交互部分,感兴趣的同学可以自己去看源码,都在 examples 目录中,我这里只说一下本质的原理。
想要做到在线换肤,并且实时预览,需要借助 server 的帮助,比如主题可以通过一个配置去维护,用户做一系列操作后,会生成新的主题配置,把这个配置通过接口提交的方式告诉 server,然后 server 会根据这个配置做返回生成新的 CSS(具体的实施的方案未开源,大致会做一些变量替换,然后编译),新的 CSS 的样式就会覆盖默认的样式,达到了切换主题的目的。
安装&引入
实际上 element-ui 会把所有组件打包生成一份 CSS 和 JS,官方也提供了例子:
-
<!-- 引入样式 -->
-
<linkrel="stylesheet"href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
-
<!-- 引入组件库 -->
-
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
工程化
前端对于工程化的要求越来越高,element-ui 作为一个组件库,它在工程化方面做了哪些事情呢?
首先是开发阶段,为了保证大家代码风格的一致性,使用了 ESLint,甚至专门写了 eslint-config-elemefe 作为 ESint 的扩展规则配置;为了方便本地开发调试,借助了 webpack 并配置了 Hot Reload;利用模块化开发的思想把组件依赖的一些公共模块放在了 src 目录,并依据功能拆分出 directives、locale、mixins、transitions、utils 等模块。
其次是测试方面,使用了 karma 测试框架,为每一个组件编写了单元测试,并且利用 Travis CI 集成了测试。
接着是构建方面,element-ui 编写了很多 npm scripts,以 dist 这个 script 为例:
"dist":"npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme"
它内部会依次执行多个命令,最终会生成 lib 目录和打包后的文件。我并不打算介绍所有的命令,感兴趣同学可自行研究,这里我想介绍一下 build:file 这个 script 做的事情:
"build:file":"node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js",
这里会依次执行 build/bin 目录下的一些 Node 脚本,对 icon、entry、i18n、version 等做了一系列的初始化工作,它们的内容都是根据一些规则做文件的 IO,这么做的好处就是完全通过工具的手段自动化生成文件,比人工靠谱且效率更高,这波操作非常值得我们学习和应用。
最后是部署,通过 pub 这个 npm script 完成:
"pub":"npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh"
主要是通过运行一系列的 bash 脚本,实现了代码的提交、合并、版本管理、npm 发布、官网发布等,让整个发布流程自动化完成,脚本具体内容感兴趣的同学可自行查看
总结
至此,element-ui 的组件库的整体设计介绍完毕,可以看到除了这些丰富的组件背后,还有很完整的一套解决方案,很多经验都值得我们学习和借鉴,不完美的地方也值得我们去思考,其中有很多技术细节可以深入挖掘。