头条小游戏入口 ttc带你看动漫?很多人不了解,今天趣百科为大家带来相关内容,下面小编为大家整理介绍。
我们今天要讲的话题是构件库从零到一的设计与实践。大家看这个题目应该就很清楚了。作为前端工程师,平时的开发离不开组件库。你对Ant Design、Element等组件库非常熟悉,但是如何自己设计一个组件库或者最好的做法是什么?今天我打算借此机会和大家分享一下百度外卖的经验。
这是基于Vue的github的组件库,我们自己实现的。这是地址,有兴趣可以看看。虽然在github上维护,但基本都是内部使用,所以对外没有做太多宣传。
回到今天的话题,如何从零到一建立自己的组件库。这是我们今天的具体内容,首先是认知和目标,构件库的规划,具体的架构设计和实践,最后是构件化的设计思路。
这部分具体包括什么是组件库,是什么概念,我们为什么要做这个组件库,具体的好处是什么,因为我们都是在公司,我们做的相关的事情也会为公司产生一定的收益。能不能具体做,或者需要做什么,怎么做,什么时候什么时候完成?
可能有的同学会说,我可以直接开始写代码,但是需要强调的是,组件库不仅是技术,还有方法论,这很重要。这个方法论后面会跟你详细解释。
现在我们做这些组件肯定是要反哺业务的,如果业界或者是相关的社区已经有很优秀的轮子了,你又重复造轮子或者是你做出来的东西还是跟别人有一定的差距的话,你的投入就会显得没有具体的产出,另外是团队的构成,比如说同学他是否掌握具体的相关的技术,或者是团队同学对于一些技术栈的偏好之类的,这些事情也是对我们具体做这个事情也是有影响的。
我们具体的目标,当时我们做具体的这个组件库的时候,目标一定要明确,内容是一个基础的组件库,就是他是没有任何业务相关的逻辑,因为我们做组件库是强调复用,业务的逻辑是经常变化的,但是基础组件的交互是比较固定的,另外是组件的数量,整个库的容量是多少,具体的形态是什么样的,分发,以那种方式提供给用户,用户是可以使用一些其它的拷贝或者是线上资源方式,另外是维护人力流程这块。
接下来我们就开始说一下具体的在做这件事情之前具体怎么样对组件库做一个规划。
我们说规划的核心是什么,实际上是两个字是取舍,取舍是做什么事情不做什么事情,具体是怎么样分工,具体的时间怎么安排。
我们这个组件库是做技术组件库,不做业务组件库,我们做高频的组件,一定是在我们的业务里面做比较高频的组件我们才会考虑开发,可能是业务里用的比较小众的情况下就不会选择开发,还有一点没有框架的依赖,比如说jquery等 。。为什么没有框架依赖,相关的框架会增加我们体系的大小,另外组件库本身不应该有具体的倾向性的,因为它是面向开发者的,如果组件库有相关的倾向性很可能会对开发者造成一定的困扰。
说一下分工这块,我们组件库是一个团队合作的项目,这个组件库是聚焦在几个人身上做还是大家每个人有一个这样的情况,首先我们是觉得是需要结合一些业务项目的情况,我们不能专职做这个东西,平时有业务的开发,我们要保证投入,通过一些相关的设计方式我们正式质量的差异,另外我们要落实具体的规范。
那接下来是落实具体的规范就给和大家分享一下我们相关的组件库的规范。这个事情是对组件库来说显得尤其的重要,因为组件库有可能是一个团队协作的产物,或者组件库本身是一个整体,必须要有相关的规范。
我们认为组件库这块的规范有很多,总结了一下,比如说评审的规范,这个组件库应该是什么样的,API怎么设计,或者是属性相关的东西应该怎么设计,评审的规范,另外是代码的规范,代码应该有什么,遵循一个什么样的代码规范,另外是开发的规范,大家开发的模式是一样的,最后把这个规范,因为组件库本身是生态最后肯定离不开做维护,相应的维护也是系统规范的。
首先这个是一个基本的规范,大家可以看上一页的图,代码的规范和开发的规范,这一部分是在组件库本身的维度上面我们可以对他做一些约束,首先是在我们的开发规范里面具体的,我们是用ES6去做,ESLINT使用我们百度的具体的代码的规范,相关的东西大家可以去到我们百度FEX的github库中搜到,做一些规范检查,我们最后的CSS的语言是使用的LESS,说到规范,大家可能有一些同学知道会有一些,比如说是OOCSS,BEM这些规范,这种规范现在在社区内的意见并不是非常统一,现在的框架,比如说Vue可以通过scope把组件Css与外部给隔离掉,或者是CSS IN JS这种相关的技术给他可以做到,去隔离这种CSS的污染,像BEM的规范,实际上是会增加一些相关开发的负担,因为他是跟组件本身是一个平行的状态。
在命名的规范这块是可能对于我们组件库来说,有具体的组件名,具体的API相关的都会涉及到命名,实际上这也是一个比较难的一个事情,因为首先你需要简明扼要还要统一,相对来说就是每个平行的组件,类似的名称是要统一的,肯定要语义化,方便开发者去理解,还要贴近我们原生的相关的命名。
贴一些例子,就是大家可能是可以看到这上面的一些,比如说我们列举的一些好的例子与不好的例子,大家可以看一下。
对组件库来说他是基于一个框架相关的,比如说像Ant Design他是属于一个React相关的组件库,Element是基于Vue开发的,首先这些框架本身的思想是不尽相同的,相关的开发范式也是不尽相同的,这些也是针对框架做不同的规范。
举个例子,比如说在Vue对你定义的一些数据做一些简单的处理,表达式说清楚就不必要计算属性/method这种具体在代码里写的东西,这个也是我们推荐的方式。
最后是开发规范,当然有一些同学喜欢用html/css/js三个文件这种方法,我们统一定的文件的方式,首先他是可以和webpack很好的去做一个相应的解析,我们这种底层的具体的做打包或者是做相关开发的东西都是用webpack.另外样式分离我们不会在Vue去写,我们单独的把样式抽离出来,能够更统一的使用相关的一些LESS变量,会比较方便,我们还要统一一些工具库,DOM操作,通信相关的一些库,我们会统一具体的动画库,动画库在Vue里面就是trasition.还要统一开发环境和展示站,最后维护就是我们提交的是使用github这种相关的工作流,。
上面可能是说了很多类似是规划和规范相关的东西,我们之前说的方法论相关的一些。下面是着重给大家介绍一下具体的架构设计和工程化这块的内容。
大家可能是可以打开看一下这个图,这个是我们的一个具体的结构的设计,大家看下面的紫色的这部分是我们具体的组件的一个容器,包括我们的Assets,比如说图片字体这些的静态资源,DEMO这个是专门写组件的文档的,对于每一个组件是一个单文件的Vue,我们CSS刚才说了已经是分离出去了,相关的一些工具库和一些相关的Mixin,左边这块是一个单页,我们的组件肯定是需要有一个展示站的单页,这块我们的开发环境和我们的文档是统一的,肯定是离不开为这个组件库写文档。
在说一下我们的CSS架构相关的,首先之前我们提到过我们是用这种语言写的,预处理,首先是需要一个环境适应性,当前只在组件的内部去产生生效,不会被其它的东西污染,还要具体的相关的交互是要统一的。我们的主题是可以更换的。另外是一些其它的高度的自定义,这块是提到一个Bootstrap, 这个东西大家很熟悉,就是可能是很多同学并没有深入利用好他的实践,就是这个库的话内部的实现是比较精妙的,具体的我是建议大家可以看看这个原码,我们这块的实现也是去参考了Bootsrap,有一些同学会问为什么你们不直接基于Bootstrap来做,我们最开始的时候我们的确是基于这个做的,但是后面实际上会发现一些问题,比如说如果说你本身的站点原来大量使用Bootstrap的话, 可能是会对这个做一些自己的定义,比如说是btn-info这样的类名可能会被做一些自定义,如果我们在这里面直接使用这个类名肯定是会被污染的。对于关于具体的我们这个长什么样,很大程度上是由我们CSS决定的,如果你一开始做一个组件库的话,如果说你是一个前端或者是你是一个设计都很擅长的同学,你可以自己搞一套,但是对于很多前端工程师不是非常懂设计语言或者是其它的情况下最好是参照一些业界已有的语言,比如说像Material Design, Ant Design这样的设计语言。
大家可以打开这个图看一下,这个是一个CSS具体的结构,首先是左边是基础相关的东西,可能是一些CSS的,比如说Noramlize, Reset做一些基础的工作,我们定义相关的颜色相关的字体,图标,grid栅格相关的东西。
在颜色的话对于组件库来说肯定是会定义一个主色,另外一个是info是体现一个信息传递,success体现一个信息的成功或者是一个操作的成功,warning体现一个警告,error体现一个错误的操作,类似的这些基本色一定要定义好。在我们从黑到白定义的一些比如说是灰度方面的颜色,less相关的函数是可以实现的。
图标这块是先想说一个问题,LICENCE是很重要的,看他是不是MIT的,如果是一些付费或者是商业使用某些图标是不让你用的,虽然我们做的是内部的组件库,我们在github上做这个事情,所以我们是使用开源的图标库,第二个是字体的资源的打包或者是分散,比如说字体大家应该很熟悉,现在的icon字体会有一些svg, woff, ttc,这样类似的几个文件,他们可以说是这几个文件是你必须要加载的,具体的分散社区有相关的方案,把所有的icon,分散成一个一个的js文件,当然里面是Svg,这样的话如果说你是对单组件,可以单独发布出去使用,又让他体积最小的情况下分散的方案也是很不错的。
说到动画,可能在组件库的维度某些组件的动画行为是不一样的,比如说Tooltip和Popover,可能tooltip你hover到某个元素上马上会就出来,但是popover就会慢一点,这两者的动画都会有一些差别,这里面可能是有用函数定义不同的参数做一些事情。
在这块我们是采用24栅格相对来说控制力度更细一些,(英文)现在是我们的栅格系统也是支持FLEX-BOX的,但是这个具体的来说是用LESS的循环是可以非常比较优雅的实现。
但是我们的开发里面可能是对组件库来说离不了文档,但是在这里面是去和大家展示你的组件是什么样的,你的不同的形态,在不同的应用场景下面是什么样的。另外是你的文档系统是要把代码贴出来,怎么样去使用你的组件,你组件实现你这个效果的源码是怎么样的,组件的props属性是用哪些,API 是用哪些,这个是文档系统应该做的,对于组件库也是必不可少的,我们这里是使用自定义的vue-loader,他是会同时展示我们的DEMO和代码,将markdown写在vue文件里的,,我们这样实现一个开发环境和调试环境还有展示站都是统一的效果,另外是业界很多文档系统是基于md做的,我们是为什么基于vue做,因为在md的代码里面写vue是没有高量提示的,这个对开发体验是会有一定的困扰,当然是基于md这样的文档系统复用度比较好,比如说你是使用一个react的组件库,也可以将文档系统作为一个基础设施来用。
大家可以看一下我们具体的这里面的一个源码是这么写的,具体的代码的书写的方式。
文档系统主要是使用了markdown的解析引擎和prismjs,这个是用来做高亮的,不像highlightjs是运行时做的高亮,prism把markdown都PARSE成特殊的html,我们写好相关的CSS就可以很好的去展示我们高亮的效果。另外做一些正则处理。比如说双括号这个东西需要做一些特殊的处理,在Vue解析模板的时候就会把相关的解析结果替换掉。,这样的话就不太好,有一些正则方面的一些处理。
我们聊一下具体的工程化,组件怎么样提供给用户,什么样的形式提供给用户,组件怎么样做,持续集成是怎么做的。
组件要怎么提供给用户,有两种方式,单组件是面临怎么样处理公共资源的问题,比如如果你没有把ICON分散掉的话,就是必须在你的组件是依赖ICON的,还有版本比较的问题,你整个组件库对外提供的版本和你的单组件具体的自己做的版本升级,这样的版本问题怎么样处理,组件间相互依赖的问题,一个组件依赖另外一个组件,依赖的组件升级的版本,但是被依赖的组件对之前的老版本相关的依赖相当于都得改,但是在整库打包这块,打成一个JS和CSS提供出去,好处是你整个组件库是某一个版本,这样的话对版本控制来说压力会比较小,但是你要面对的问题是代码大小。整个组件库几十个组件在一起,你怎么样按需做这个事情,我只要加载某一个组件那怎么样。
对于像使用webpack的项目而言,提供源代码是最优的选择,因为他是可以开发者也是可以看到你的源代码具体怎么实现的,比如说你要做一些按需也非常方便,但是对于我们的FIS,可能同学不知道有没有听过,是我们百度内部的一个整体的一种前端的解决方案,可以说跟webpack存在的一些功能的重叠或者是竞争,但是两者的打包有一定区别,FIS里面也是会有一些按需的方案,但是使用起来有时不如webpack的那么方便。所以我们内部这块大多数是FIS,有一些是同时使用fis和webpack的,我们在这块是打包提供给用户的。
持续集成我们这个项目是在github上维护,我们使用circleCI,这样的一个系统,相当于我们写好原代码, 一些产出一些展示站,组件库的产出就会自动更新,这里我们是有一个帐号,而不是一个具体的实体的人,因为这样的话,这种代码他并不是一个有意义的代码,机器人做这个事情,在github的一些统计上面来说我们就会避免一些不必要的, 看上去像代码提交的很多的情况,把这些活交给机器人的帐号。
因为这个时间有一点超了,接下来是给大家分享一些我们组件化设计相关的一些思考。
首先大家看一下这个图,基础组件到上成的分装,这个比如说大家看具体的例子的时候会比较好理解,一个Input他需要一个Icon,比如说是要一个X的,可以把这里面的一个东西清空的,他就可以进化成InputNumber, Suggesion, Select, Datepicker等 。所以说对于一个组件库而言这种基础组件是必不可少的,因为如果说没有去做基础组件的话那么比如说两个同学直接开发一个select,开发一个datepicker,这样的话两个人写的input,长的不一样,这个是一个最直观的痛点,另外一个是两个人input他们的一些props, api也都不一样,这样的话我们后期维护起来的成本比较高,所以这个是定义好基础组件,这个是非常重要的。
接下来是一些通用解决方案的分装和引用,原来是动图这个是静态,接下来是popper弹出层,很多组件都可以用的到,我们最后是选用popper.js的方案,可以说是位置的引擎,比如说中间这个tooltip的提示,黑色的提示,他如果说是遇到屏幕右面的时候会自动计算的位置把他打造相反的位置就是左面。比如说右面这个select,随着你滚动组屏幕会自动跑到上面去,这样的话体验会比较好。
另外是基于Vue本身,我们很多跟VM打交道,我们在通过这种插件的方式,可能是熟悉Vue的同学会比较了解他是插件的方式,使用是很方便的。如果是在我们的根节点APP上把组件库作为插件引入,就会有挂载示例的方法。
比如说分散数据的方法,上下两种方式,我可能是这样的话是像上面的样子直接是一个select,我在这里面相当于是用这个data,比如说LI这个东西模拟option这个方式,这样的话就是说我降低了自定义的能力,比如说想对这里面的option做一些样式的处理,或者是做一些数据上的处理,都做不到了,所以如果说是这里面提供的这个来说,第二个方式是会比第一个方式自定义能力要强一些。
下面是具体对今天说的内容做一些总结。
首先是技术和方法论在组件库这块,要做具体的深入的调研,做一些取舍,相关的规范一定是要对团队的相关的成员做一些约束的,相关的工作流程与团队成员做一些培训。
组件库这个坑是比较大的,除了我们纯粹的写组件之外一些文件系统,持续集成,我前面提到的之外,比如说是像测试一些相关的工具链,一些国际化相关的东西,如果说你要做一些特别大的开源组件库也是不可避免的,一些附带的资源,比如说他可以反哺一些UI的设计, 可以参考这种组件库的相关的交互。今天大概的内容就到这,插播一条,我们现在外卖的前端也是在招聘,我们现在做的业界比较新的技术都会在使用,比如说vue, react, react-native, nw.js等等,而且我们的技术氛围很浓厚的,大家可以考虑一下,这个是我邮箱,给大家推荐一个公众号,百度外卖技术团队的公众号,大家可以扫二维码 关注,会经常的发一些技术的文章大家可以关注一下。