然并卵的前端工程化
近些年听“前端工程化”这几个字听到耳朵起茧了。
前端的复杂度越来越高,很多项目已经很难单枪匹马完成了。前端这个行业,又出奇地拥挤——门槛太低了,但天花板却不低,导致前端开发人员的水平参差不齐。哪怕你自诩水平ok,出门在外难免也会碰到一两个猪队友。所以工程化越来越多地成为前端的痛点。
但是,你懂工程化吗?
如果你是HR,你去面试前端求职者,特别是刚毕业的前端求职者,你问他“怎么理解前端工程化”?你大概率会听到下面这些说法:
“代码库要使用git之类的版本管理工具做代码版本管理”,
“要使用npm或yarn之类的包管理库去管理依赖”,
“要用eslint做语法检查和格式化”...
然后呢?
你把这些手段都加上了,你的项目就能迭代得很好?它经过千万次提交集成之后还是金山银山而不是屎山?
工程化的本质
什么是工程化的本质?听到工程化,我们脑海里第一时间会想到制造业和建筑业。制造业有标准流程、分工、质检等概念,建筑业有脚手架、预制件、结构、功能分区等概念。对这些概念展开联想,不难提炼出工程化的核心是通过一定的手段降低复杂度,有质量地解决一个复杂问题。
本质其实是一样的,git、npm、eslint这些工具其实也是软件开发行业借鉴了传统行业的工程化思路而产生的。
但是软件开发,跟这些传统行业,又有一定的区别:
- 我们的生产过程是不重复的。我们开发出一个功能,我们不需要对这个功能再开发一遍,而传统行业很多时候会不断运行一个标准流程不断地交付相同的产品;
- 我们的生产过程是迭代的。我们开发出一个功能,可能又要以当前版本为基础,迭代需求,再开发出新的版本。
如果用一个职业来形容软件开发,最恰当的,应该是“城市规划师”。
一个城市的发展,并不是一开始就敲定了的。但是无论如何,建城之初,我们需要有一个慎重的规划:
- 这座城市哪个部分是商业区,哪个部分是住宅区,哪个部分是工业区;
- 不同的分区又决定这座城市的基础设施:哪里应该多盖学校,哪里应该多点生活设施,哪些需要发达的供水供电系统....
把这一切规划妥当之后,城市就会按照规划进行演化:
- 越来越多的工厂落户工业区;
- 住宅区慢慢地人来人往,生活设施也会越来越完善;
- 商业区会越来越多商家进驻,各种商业活动越来越频繁...
而城市的发展又不是100%按规划演化的,有可能面临调整或重新规划:
- 可能住宅区的人口越来越多会挤占其他功能区的空间,
- 可能城市为了环境优化的考虑减少工业区的范围并不断地往郊区迁移...
所以,软件开发的工程化又跟传统的工程化有一定的区别,在某些方面难度更大,不能机械地去考虑这个问题。
看一个前端工程化的失败例子
作为前端,大家都很熟悉vue的工程源码目录。
|-src
|-compoments
|-xxxx.vue
|-router
|-router.ts
|-store
|-xxxStore.ts
|-styles
|-xxx.scss
|-views
|-xxxx.vue
|-main.ts
|-App.vue
大壮和小美是一对勤劳的前端搭子,他们想要一起合作开发一个烂大街的商城App。大壮和小美都觉得前端工程化很重要,所以他们在创建项目脚手架的时候,就把所有的功能都满上:typescript、scss、eslint、单元测试、端对端测试...
然后他们觉得一切准备就绪了,简单分个工,先做两个模块,大壮开发个人信息页,小美开发商城主页,哐哐哐立马撸起袖子干。
大壮开发个人信息页前,他首先简单考虑了一下,觉得很多组件是可以重用的,就在compoments里面新建了几个vue组件;
然后觉得个人信息在其他页面也会用到,属于共享的状态,所以他在store文件夹里面,又创建了一个profileStore.js文件;
接下来在路由文件router.js中定义个人信息页相关的路由;
最后在views中开发页面。
开发着开发着,问题就来了。
个人信息页有很多小组件,大壮往compoments里面塞了好多个小组件,他觉得可能这些组件是通用的,而实际上小美是用不上的,每次小美都需要在一大堆组件中找自己需要的组件;
个人信息页开发过程中有些小调整,有时候需要添加新的组件,删除旧的组件,有时要修改router文件,store文件,每次调整都要在各个文件夹中穿梭,大壮开始怀疑人生了。
后面他们想要做一个其他的App,这时候觉得他们之前开发的商城个人信息页是可以重用的,想要先扒过来用,面对散落在compoments、router、store、views等各个地方的个人信息页的实现,大壮进一步怀疑人生...
再看一个前端工程化的成功例子
其实我们身边就有成功的前端工程化例子。我们每天都要摸上千百遍的vscode就是前端工程化的标杆。
我们不妨对照着vscode的开发文档,看看vscode是怎么组织开发的。
我们使用的vscode,是由基础应用+扩展组成的。vscode的核心团队维护着vscode的基础应用的开发,基础应用力求稳定、高效,并且提供合适的API供扩展开发使用,允许这些扩展改变vscode的外观、添加页面、改变操作的默认行为等。而我们使用的大部分功能,都是扩展提供的。
vscode为扩展的开发提供了工程脚手架。这个脚手架可以让代码方便地在vscode上运行和调试,同时,这个脚手架也可以使用typescript、scss、eslint、单元测试这些特性。
vscode的每个扩展,都由独立的团队或者个人开发,两个扩展之间的开发人员没有沟通,也没有协作,大概率也完全不认识。但是这些扩展却都能集成到vscode中,用户想安装就安装,想卸载就卸载,想启用就启用,想禁用就禁用。
工程化成功的关键
聊到这里,可能很多朋友已经知道我想要强调的是什么了:关注点分离才是工程化成功的关键。
软件工程化最大的挑战是应对变化。而开发中引起变化的点,往往是业务。一个业务往往由一个团队负责,一个业务的变化往往只会引起关联业务的变化,而其他业务往往保持不变。一个需求的变化,只会给一个团队或者少数几个开发团队添加开发需求,而这些开发团队可以独立应对这些变化而不用每次都大动干戈和其他团队进行协作才能完成需求,这才是工程化的关键。其次,才是对工程化工具的娴熟使用。
今天先唠叨到这,下一期举个栗子,实现一个前端工程化的demo,再见。