看到标题,一般会有两种反应:
「哇~好高大上啊!」
「嗯,这个话题真大……」
——的确如此。
深情前戏
我不生搬硬套那个什么百科来说啥是「面向组件」和为啥这么做,而是从工作现状以及自己思考的角度来阐述,并试着拟出一个解决方案。
前端眼里的「组件」
对于前端开发人员来说,「组件」通常就是指页面上的 UI 组件,主要包括外观和交互。一个合格的组件应该是可复用、可定制、松耦合的,它能够代表一个事物,可以完成一个动作。
组件可以很简单,也可以很复杂。按照复杂程度从小到大排的话,可以分为几类:
- 基础组件;
- 复合组件;
- 页面;
- 应用。
对,不用揉眼睛,你没有看错!
站在更高的角度去看,「页面」和「应用」也是一种「组件」,只不过它们更为复杂。在这里我想要说的不是它们,而是「基础组件」和「复合组件」。
其中,基础组件具有简单的外观和基础的功能,而复合组件则是根据具体场景所进行的基础组件的组合和封装。
为啥要「面向组件」
在从事一段时间的前端开发之后,就会发现:
「一个系统里的页面功能怎么都差不多?」
「每个网站基本都一个模子里刻出来的!」
——说得没错!
你在 CTRL + C 并 CTRL + V,改掉相同中的不同之后,保存文件并刷新页面,点这点那看看效果——「我靠!这俩页面的交互一毛一样,怎么在那个页面好好的,到这里就不好使了?!」
1……2……3……个小时过去了,这该死的小强到底是从哪里溜进来的一点儿头绪也没有……心里窝火地一直在「MMP」,一不小心说漏了嘴——「妈卖批的!!!」
兄弟,淡定!
出现这种问题,是因为没有面向组件开发。那些你所觉得的「相似」的部分,就可以提取出来形成组件,以备再次出现类似场景时使用。你以往所依赖的「CTRL + C / V 大法」,讲道理,是下下策中的下下策。
等组件积累得多了,页面就不再是自己苦思冥想一行一行代码挤出来的,而是随手从现成的库中拿来一个一个组件拼出来的。如此一来,不仅页面功能更加稳定,前端开发也能脱离枯燥而变得更加有趣,告别那一整天大部分时间在摁臭虫的鬼日子——
后端:「什么时候可以联调?」
前端:「页面早就弄好了,接口呢?」
后端:「……」
「面向组件」是啥啊
换个词,「组件化」,也许更为熟悉。但,所以,到底是指什么呢?
对于抽象概念的含义,每个人都会有自己的理解,正所谓「一千个读者心中有一千个哈姆雷特」。有人会说:
就是把相关的 HTML、CSS、JS 和图片等文件放到同一个文件夹里吧?
——没啥毛病。
在进行面向组件开发时,确实会将同一个组件的相关文件放在一个文件夹中,然而,这并不是核心。重要的是,能够将一个复杂的东西恰如其分地拆分成更小且独立的,高内聚低耦合,让别人不必了解其内部运作原理拿来就用——这是思想,也是能力。
进入正题
「面向组件」开发,或者说「组件化」,由来已久,并不新鲜。这个话题在前端圈儿也炒了很多年了,这个框架那个库的层出不穷,为什么我现在还要再拿出来嚼一遍呢?
理由很简单:
- 在别人那不成问题的,在我这可能很是问题;
- 对别人很管用的工具,对我可能并不太适用。
别人爽的姿势我不爽
要进行面向组件开发,前提是得有可行的技术方案,依我看,需要必备几点:
- 组件的样式和交互不会意外地被外界干扰——对外隔离;
- 一个组件相关的资源要在我用到时再给我——按需加载;
- 让前端技术不那么强的后端开发也可以用——门槛低。
红极一时的充分发挥 jQuery 特长的两个宝儿,jQuery UI 和 Bootstrap 提供了很多 UI 组件,对后端开发人员也很友好,看起来符合要求。但从它们组件的实现方式以及资源加载形式来看——
jQuery UIBootstrap
现在的前端圈儿,一提到「组件」,大多数人的兴奋点都在 React、Vue、Angular 等 MV* 框架上。它们是很不错,不仅满足了「对外隔离」和「按需加载」,还大大地提升了前端开发的效率,能大红大紫成这样自有其道理。
我司的业务是 to B 的,因此前端开发场景很「明确」,基本可以简单粗暴地理解为:「前台」就是移动端,「后台」就是桌面端。
前台开发用的是基于 React 和 Ant Design Mobile 二次开发的框架。It works well,能够 hold 住当前的需求。然而,后台开发就不一样了。
我们后台的需求很多,比前台多,并且源源不断地加速增长;我们后端的人员很多,比前端多,并且不成比例地持续加人。这就导致了一些问题:
- 每条业务线的前、后端开发人员比例平均为 1:4;
- 一个前端人员可能会去支持一条业务线的多个项目;
- 一个前端人员可能会去支持多条业务线。
——人不够用!
该如何去解决呢?从公司的角度出发,肯定是要降低成本——不靠招更多的人,而是靠改进方法最大化利用已有资源——让前端人员能够写更多页面,让后端人员也能写页面。
为了达到上述目的,我在 jQuery 和 Bootstrap 的基础上封装了一个用于后台的框架。
虽然在写 JS 时已经节省很多时间,也有几个后台系统是由后端人员独立开发的,但还是要写一堆 HTML 代码。就连前端人员都会觉得有点心烦,更别说后端人员望而却步了。
在使用 React 组件时可以少写不少 HTML 标签,可是,但可是,后端开发人员会去写吗?他们会想写?!
综上所述,MV* 类框架并不能解决我司后台现阶段所存在的问题——
ReactVueAngular
有人不满了:
你这也不行,那也不行,那还有啥了?!
——大大的有!
大家爽的姿势才正确
有那么一个被各种 MV* 框架的光辉所掩盖的,虽然有那么点缺陷但却很有实力且颇具潜力的技术——是的,就是 Web Components!光从名字来看,不难想象它正是为了解决前端组件的问题而出现的。
Web Components 由可以彼此分开使用也能够协同工作的四个部分组成:
- Custom Elements——定义新的 HTML 元素;
- Shadow DOM——隔离 DOM 和样式;
- HTML Imports——声明要引入的 HTML 文档;
- HTML Templates——定义可复用的 HTML 片段。
因为是 W3C 的亲儿子,使用者可以像对其他如 <div>
、<p>
一样对待由 Web Components 封装的组件——完全照顾了前端技术不娴熟的后端开发大大们。
被你说得那么神,我咋就没听说过呢???
——问得很好。
既然是 W3C 亲儿子,从出生到被世间,尤其是被那些「有权有势」的所认可需要时间——它出来多年仍未成为推荐标准,兼容性不太理想。
可以说,兼容性和不稳定性成了推广 Web Components 的致命伤。
然而,并不用觉得过于扫兴。
已经有 polyfill 帮我们填了一些坑,并且还有几个简化开发的库,如:Polymer、X-Tag 和 Skate 等。再加上,我司的后台是对内的,几乎只需考虑 Chrome 类浏览器,兼容性缺陷基本可以无视。
这样一来,开发一套基于 Web Components 的组件,是不是既让前端人员爽了,又让写页面的后端人员爽了呢?
心里美滋滋〜( *´艸`)
高潮来了
现在看来,前端团队的面向组件开发的技术方案似乎已经确定了:
- 移动端用 React 和 Ant Design Mobile;
- 桌面端用 jQuery、Bootstrap 和 Web Components。
如果以为这样就好了,那真是 think too much!
除了啪啪啪,什么都要快!
随着公司业务的发展,已经将触角伸向了正不断发力的微信小程序。虽然目前在这方面的业务很少,但我相信相关需求会接踵而至。
众所周知,微信小程序的开发自成体系,对于我们前端开发人员来说又多了一个东西要去学……不过,作为一名前端工程师,早就习惯了这比女人的心情还变幻莫测的前端技术。
稍微往远点看,如果公司的业务需要,可能还会要做出来没多久的支付宝小程序。没准未来又出现了别的什么小程序,或者其他具备组件特性的新的什么轮子。
为了支持公司的业务,每出来一个新的东西,前端人员就不得不去学怎么去用并且用好它。从团队管理、团队协作以及开发效率等方面来看,会产生一些严重的问题:
- 得每个人都掌握所用到的库/框架才能任意分配任务;
- 技术栈杂乱而不便于进行培训和代码质量管理;
- 抽取沉淀组件库将要变得异常艰难。
这些问题在快速发展的业务的催化下,就会导致:
- 开发时间太少啊太少——加班!加班!!加班!!!
- 前端人员不够啊不够——加班!加班!!加班!!!
要是加班还解决不了怎么办?那就项目延期呗。
可项目延期会耽误公司的业务啊!那就……
想个新姿势
为了规避以上问题,为了以不变应万变,为了让支持业务的前端开发童鞋能够无视运行环境而有始终如一的便捷开发体验,我试着想了一个解决方案——通用组件编写规范。
所谓的「通用组件编写规范」主要包含两部分:组件定义和目录结构。
组件定义使用 ES6+ 语法,采用类的方式,要兼顾组件的属性映射、数据绑定、事件处理、生命周期等特性。类的各成员的设计参考现有流行库/框架,但不同于它们。
目录结构遵照前端开发的「关注点分离」原则,一个目录代表一个组件,一个 JS 文件就是一个组件定义。组件的样式用 Sass 来写。
通用组件编写规范解决的是开发阶段的问题,是支持业务的前端童鞋所要重点关注的,接下来的事情就交给构建工具去完成。
贤者时间
正如开头所说,「面向组件」开发是一件很高大上、很大的话题,想搞出一套「Write once, Run anywhere」的组件开发方案更是听起来天方夜谭。
我已经做好了被各种泼冷水的心理准备,也许在实现的道路上困难重重、踩坑无数,到最后被证实这确实是异想天开;但为了能让公司业务的发展不受前端开发的阻碍,让团队中的小伙伴们减少加班次数,关于团队留下更多美好的记忆,不会放弃前端开发这条不归路,我愿去一试!!!
要发车了,没时间做更多解释了!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。