又是一年春节到来,自己也从事前端也有2个年头了,也越来越觉得前端的东西变化太快,所以萌生了系统的归纳一下所学的东西。
这篇博客从近几年最热的“前端工程化”起手,结合个人工作中遇到的问题、经验做的一些总结。
起子
所有能降低成本,并且能提高效率的事情的总称为工程化。
这两年不管工作还是学习的时候,前端工程化、组件化的声音一直萦绕于耳,最开始以为用下webpack就是工程化,用vue就算组件化了,还是图样。随着公司前端团队人员的增加和项目的迭代,自己对这5个字的理解也深入了一点。
大学里亦学过《软件工程》这门课,现在认真回想起来,其实我们在谈前端工程化的时候,何尝不是在讨论软件工程。
前端工程化需要考虑哪些因素?
工程化需要考虑的因素也就是前端工作中所面对的三板斧:HTML、CSS、JavaScript,可以像DOM树一样,再往下一级延伸
本人总结经验,认为前端工程化主要应该从模块化、组件化、规范化、自动化四个方面来思考,下面一一展开。
组件化
组件化≠模块化
一开始我对这两点有些混淆,直接导致后续理解出现偏差,故放在第一个来说。
模块化是从文件层面上进行拆分,而组件化是在设计层面上对用户界面进行分解,大到一个网站的导航,小至一个单独设计的文本框。
就像一辆自行车,轮子、把手、脚踏板都可以看做一个组件,我们生产好这些零件,制造自行车的时候就把这些零件组合起来就可以了。
组件化的目的是一次开发,多次复用,从而减少重复的工作
组件化实际上是一种按照模板(HTML)+样式(CSS)+逻辑(JS)三位一体的形式对面向对象的进一步抽象。
拿最近项目中用到的 日历 组件来说,在填写表单内容的时候,使用日历组件填写日期是一种常见的使用场景
最开始项目中是用到单日历组件,当时开发也是按照单日历的样式及工作制作的,如图:
在后期迭代时候,产品部门提出需要将单日历换成双日历以选择日期范围,并且双日历增加联动功能(起止日期范围最大90天,结束日期不能小于起始日期),在听完产品改动的需求后,个人觉得工作量并不是很大,除了为单日历添加禁用逻辑外,剩下的逻辑都是双日历中。
下面是双日历效果图:
可以看看俩文件的目录:
相比单独设计一个双日历组件,时间消耗和文件大小都降低了许多,另一方面还达到了视觉统一的目的。
明显的好处第一点是有效减少工作量,第二点则是便于统一修改,譬如某天设计师将修改了字体大小和颜色。此时我们只需要找到该组件文件进行调整即可,而不用去修改使用到该组件的所有页面。
或许以后前端工程化会添加“组件文档”,标明I/O、作者等信息,就像我们在使用别人的jquery插件一样,不同的是前者是面向我们团队内部,后者是面向公开。这样对于我们项目维护工作来说,减轻了后续开发人员的压力。
模块化
简单来说,模块化主要是在开发过程中将一个大文件拆分成小文件,一个大功能拆分成小功能的组合。
这点和我们在前端优化中提到的文件合并并不冲突,因为前者是开发过程中,另一个是在生产环境里。
当然,谈到模块化构建,不得不考虑到模块间的 耦合性 和模块的 内聚性 。
从经验来看,一个优秀的模块设计应该首要考虑这两点,做到模块间低耦合、模块内部高聚合。
千万不能为了模块化而模块化。
AMD、CMD、CommonJs所做的工作就是实现模块的调用,也就是我们开发过程的 分离
通过以上方式我们可以将文件拆分成不同模块,模块也内部拆分成不同的代码片段。
此时我们就可以借助Webpack等打包工具将模块打包合并成一个整的文件,便于减少http请求,从而优化页面加载。
模块≠文件,而应该是一个特定功能的集合
规范化
模块化和组件化保证了我们的开发效率,可以让我们一个人能够高效的生产,但是实际开发是需要一个或多个团队进行协作的。
所以这里提出的“规范化”,其实就是对团队中每个开发人员的规范要求。
规范化是保证项目能够持续运作的关键,同时也是项目质量的一个判别标准。
下面是前人总结+个人归纳的一些规范化指标:
- 文档。需求文档、接口文档、测试报告的规范。
- 工具。框架选型、协同工具、测试工具的统一。
- 编码规范。javascript,css,html。
- 质量规范。拓展性,维护性,安全性。
- 目录结构的制定
- …
第3点对于开发人员算是重点,也是一个码农的技术能力的体现,也是最不容易控制的一点。
建议使用ESLint、JSHint、StyleLint等工具进行规范,减少典型代码错误的出现和提高代码质量。
只有尽可能的去满足上述的规范要求,才能保证项目后期的可维护性和拓展性,避免出现某个编码人员的离职导致他负责的功能模块难以维护。
自动化
don’t repeat yourself
前端自动化的目的是减少工作中的重复流程,让机器自动完成我们平日经常做的重复劳动。
譬如我这里CSS写了洋洋洒洒几百行,完成了chrome下的一个页面布局,但是还要兼容火狐、Safari等浏览器,或者兼容之前的版本,还得回过头检查一个个样式是否需要添加,这样的重复工作下来,哪里还有时间做更多创造性的劳动呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/* 自动化编译前 */
.some{
display: flex;
transition: all .5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
/* 编译后 */
.some{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-transition: all .5s;
transition: all .5s;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background: -webkit-linear-gradient(top, white, black);
background: linear-gradient(to bottom, white, black);
}
多出来的代码可能就是我们需要一个个去手动添加的兼容匹配。
当然,现在各浏览器也循着统一的趋势,但是市场中上古浏览器的存量还是公司、开发者不得不去正视的一个挑战,毕竟连淘宝京东前两年都得兼容IE67。也许过两年浏览器厂商都遵循同一W3C标准,但是目前你浏览这篇文章用着的浏览器呢?会不会现在你就用的是两年后的”IE6”。
主要包括以下几点:
- js自动化编译,bable等
- css预处理、后处理
- 图片资源自动化合并,不用再手动拼接雪碧图等
- 自动化测试
- more…
以上也是使用webpack、grunt等工具所要实现的目标:简化开发流程,提升开发效率。
当然,工程化≠工具化
结语
现在回过头来看标题,当我们讨论前端工程化的时候,我们就是在讨论模块化、组件化、规范化、自动化等一切提高开发者、团队工作效率的手段方法。
一切工程化的理念都是相通的,从传统制造业的流水线生产到软件工程,实践证明:工程化的程度与效率成正比。工程化的同时也降低了工作中人与人的差异性带来的影响,因为人的个体差异所导致的缺陷或者合作阻力也越少,实现1+1≥2。