什么是前端工程化?

x33g5p2x  于2022-04-22 转载在 其他  
字(5.1k)|赞(0)|评价(0)|浏览(477)

一、什么是前端工程化

虽然前端工程化的概念兴起还没几年的时间,但是对于“工程化”这个词并不是一个新
鲜词了,在其他软件开发的领域很早就已经有了高度的工程化,例如Web服务端开
发。只不过那个时候,前端工程师并没有工程化的意识,也没有必要对前端进行工程
化的操作,毕竟在那个时期,前端的开发工作只能算是整个项目开发过程中的“附属
品”。那为什么这几年,前端工程化的概念又突然成为了热点话题了呢?要想讲好前
端工程化其实并不容易,我就从下面几个方面入手,对前端工程化的概念做个简单的
讲解,仅仅是个人理解,希望大家多多交流讨论。

二、前端为什么要工程化

在回答前端工程化这个问题之前,我们应该先考虑另外一个问题:前端开发中会不会
涉及到业务?再详细一点,就是前端工程师到底需不需要了解服务端的业务逻辑,再
或者说,要不要将一部分服务端的业务逻辑放到前端来实现。这个问题没有标准的答
案,实际上应该属于工程协作问题,就是谁该干什么的问题。
最早的前端开发就是实现页面,顶多再写写JS让页面可以有交互的特效。但是随着需
求的增加,我们不仅要做Web应用,还要做App、小程序以及各种端。在这种需求日增
的情况下,必须得考虑一种新的方式,优化前端的开发工作,例如,解决代码冗余,
项目可维护性,提升版本迭代速度等等一系列的问题。前端工程化的概念也就是在这
中情况下被提出了。

三、实现前端工程化的基础——前后端分离

实际上,现在的前端工程化应该还处于早期阶段,毕竟前端工程师这个岗位也才诞生
没几年。在互联网发展的早期,Web应用很多情况下都是由服务端工程师一肩挑,前
端开发顶多是写写HTML代码,实现页面的布局,然后再把写好的HTML静态文件交给
后端工程师套模板,因为当时大部分的Web应用都是使用的服务端渲染技术,例如
Java的JSP。
这种传统模式下的协作开发效率非常低,如果在页面测试中发现了一个bug,这个bug
是由于一个ClassName的值少写了一个字母,你说这种情况到底是前端工程师的错,
还是后端工程师套模板时的粗心大意呢?毕竟一个网站上有成千上万个DOM节点,谁
也不能保证一行代码都不会写错。再假如,项目上线后发现网页的实际像素和设计稿
上存在1像素的偏差,这个时候就需要由前端工程师重新设计一次HTML静态页面,然
后再交给后端工程师继续套模板,等整个流程走完之后,你会发现一个更加严重的问
题,整个项目中仅仅是1像素的偏差,就有可能要调动整个开发团队来处理这1像素的
问题,极大的浪费了团队资源。

上面的问题也仅仅是传统开发问题中的冰山一角,面对这么多的问题,前后端分离开
发也就应运而生了。前后端分离开发,为前端工程化的发展提供了生存的土壤。随着
市场需求的不断变化,前端开发从传统的WebPage模式,转变到WebApp模式,Web产
品形态的变化也不断推动着前端工程师的工作内容发生变化。在应对各种“变化”,前
端工程师们也要设计出自己的前端开发“方法论”。

前端工程化的主要目标就是解放生产力、提高生产效率。通过制定一系列的规范,借
助工具和框架解决前端开发以及前后端协作过程中的痛点和难度问题。

四、如何实施前端工程化

明确前后端的分工,是实现前后端分离的第一步,也是后面实现前端各种优化方案的
基础。前端工程师主要负责的内容包括。
1、静态资源和动态资源处理。
2、javascript实现前端业务逻辑。
3、html模板文件的产出。
4、中间层web服务,一般由node.js实现。
5、前端单元测试。
6、前端项目部署。
其中,静态资源包括.js文件、.css文件以及各种格式的图片、媒体文件等,这些文
件不依赖于服务器,只需要在浏览器里面解析就可以了;动态资源是指HTML的模板,
如果项目不是由服务器完成渲染的SPA(单页面)应用,那我们就要考虑如何实现
HTML模板的渲染了。前端项目部署是指静态资源文件在测试服务器上的部署,以及
HTML模板文件在Node.js中间层服务器上的部署。

4.1、使用webpack实现项目构建

构建,简单来说就是编译,前端开发的所有文件最终归属是要交给浏览器去解析、渲
染,并将页面呈现给用户,构建就是将前端开发中的所有源代码转化为宿主浏览器可
以执行的代码。前端构建产出的资源文件只有三种,HTML、CSS、JS文件。需要完成
编译的内容有:

1、无法被浏览器直接识别的JS代码,包括ES6/7/8/9/10等符合ECMAScript规范的
JS代码。

2、无法被浏览器直接识别的CSS代码,包括SASS/LESS等预编译的CSS语法。

3、无法被浏览器识别的HTML模板代码,包括jade、ejs、artTemplate、
mustache等Node.js模板引擎。

项目构建其实就是为了弥补浏览器自身的缺陷和不足,是一种面向语言的编译过程。
那么,除了针对语言本身之外,前端的构建还应该考虑到Web应用的性能优化。这些
优化主要是为了减少HTTP请求,提升用户体验,包括:
1、依赖打包,将同步依赖的文件打包在一起,减少HTTP请求数量;
2、资源嵌入,例如将小于10kb的图片编译为base64格式嵌入文档,减少HTTP请求;
3、文件压缩,减少文件体积,缩短请求时间;
4、为文件加入hash指纹,以应对浏览器缓存策略;
5、将开发环境下的域名与静态资源文件路径修改为生产环境下的域名和路径;
6、文件名称的改变;
这里需要解释一下,前端的构建工具除了Webpack之外,还有其他的工具,例如
Gulp、Grunt等,为什么这里只提到了Webpack?其实,Gulp、Grunt只能算是工作
流管理工具,它们本身是不提供具体的功能,所有的构建、部署等功能都要由对应的
插件来完成,使用Gulp和Grunt只是便于项目各个环节工作流程的控制。而且,这两
款工具的话题热度和使用率远不及Webpack,Webpack虽然是近两年才崛起的构建工
具,但目前依然成为了最流行的构建工具之一,Vue和React两大前端框架的
Webpack Loader也是有官方或作者本人编写的。所以,我们在讲前端工程化构建
时,推荐使用Webpack这款工具。

4.2、使用babel完成javascript编译

JavaScript可以说是前端最为核心的一门编程语言了,也就是我们常说的“JS”,JS
本身是可以直接在浏览器中执行的,那么为什么还要使用Babel再编译一次呢?其
实,这里要解释一下,在ECMAScript2015(简称ES6)正式发布以后,前端工程师
关注的重心就由“JS”转向了“ES”,作为专业的前端工程师们应该都了解,
JavaScript ≠ ECMAScript。

ECMAScript是一个标准,JavaScript是对ECMAScript标准实现的一个子集。宿主
浏览器的API(BOM和DOM)再加上JavaScript,就组成了我们传统认知中的
JavaScript。但是随着ECMAScript的版本不断迭代更新,带来的并不是开发的便
利,由于浏览器对ECMAScript新规范的支持实现比较滞后,即使是目前最新版的
Chrome浏览器也没有完全支持ECMAScript2015(ES6)的所有规范,而且
ECMAScript2017都已经发布了,为了更好的让新的ES规范能够无缝衔接浏览器,
Babel编译JavaScript语法的作用就突显出来了。

Babel的作用简单来说,就是将浏览器未实现的ECMAScript规范语法转化为可运行
的低版本语法,例如将ES6的class转化为ES5的prototype实现。

4.3、CSS预编译

CSS作为浏览器可以直接识别的样式语言,弥补了HTML原生样式的不足,对于早期互
联网开发中,样式的要求并不复杂,仅需要少量的CSS代码即可。但是在如今追求用
户极致体验的潮流下,CSS的开发要求不断提高,复杂的CSS开发变成一件非常繁琐和
痛苦的事情。最主要的原因还是受限于浏览器的实现和CSS自身的弱编程能力。

CSS预编译器的工作原理是提供便捷的语法和特性供开发者编写源代码,随后经过专
门的编译工具将源码转化为CSS语法。

4.4、模块化开发

模块化开发和组件化开发是两个完全不同的概念,模块化属于架构层面的概念,前端
工程化与模块化的关系就类似于组装车间与零件的关系。使用模块化开发,可以解决
下面几个问题:

1、避免命名冲突。
2、便于依赖管理。
3、利于性能优化。
4、提高可维护性。
5、提高代码的可复用性。
在ES6规范发布之前,前端模块化开发主要有三种规范,分别是:CommonJS、AMD、
CMD。
CommonJS是一种只适用于JavaScript的静态模块化规范,适合Node.js开发,但并
不适合浏览器环境;而AMD/CMD规范并不是完全一致的,但核心功能是统一的,两个
规范都重点解决了浏览器对前端模块化的需求。

ES6 Module规范推出之后,前三者的模块化规范也逐渐退出前端的历史舞台。ES6 
Module是语言层面的规范,与应用场景无关,所以一个不涉及运行环境API调用的模
块可以在任何场景下运行。但是目前浏览器还没有完全支持这种规范,所以,要实现
ES6 Module规范的话,还需要使用构建工具进行编译。

4.5、组件化开发

前面提到了,组件化和模块化是两个完全不同的概念,模块化是文件层面上对代码和
资源的拆分,组件化是设计层面上对UI的拆分。从UI中拆分出来的一个结构单元,成
为UI组件,一个UI组件单元包含了HTML模板、CSS样式、JS逻辑。在页面的设计过程
中,页面上的每一个元素都是组件,页面也是一个组件,只不过页面是一个大型组
件,然后这个大型组件又由多个中小型组件拼装而成。中型组件还可以再拆分成小型
组件,小型组件再拆分成DOM元素,DOM元素也属于浏览器自身的组件,是组件的基本
单元。这种组件化开发就是前端开发的“分治思想”。

4.6、开发环境的本地服务器与Mock服务

在前端工程化开发中,通过构建工具可以将代码进行编译,然后在浏览器中进行调
试,但是在开发过程中源码的每一次修改都需要执行一次构建,构建完成后才能在浏
览器中运行,这对于前端工程师来说无疑就是一场灾难。要完美的解决这个问题,可
以使用本地服务器与构建工具结合,对源码进行监听并在修改之后触发动态构建,使
用自动化构建方式代替人工。这种动态构建是使用本地服务器解决开发层面的问题。

Mock服务解决的是前后端协作开发的问题,前后端开发人员提前约定好规范,前端工
程师通过本地服务器提供的Mock数据接口辅助前端逻辑的编写和功能模块的开发。如
果项目中需要服务器端渲染,本地服务器还需要具备解析html模板的能力,同时
Mock服务提供SSR所需的初始化数据。

前端工程师可以使用本地服务器提供的Mock数据接口,在后端人员开发的同时,进行
前端逻辑的并行开发,等到后端真实接口开发完成后,将前端请求的地址从Mock服务
迁移到服务器的生产环境即可。

4.7、规范化约束

无论是服务器端开发还是前端工程化开发,规范化的约束都至关重要。开发人员在设
计项目的整体架构时,为了考虑到项目的可扩展性、可维护性、高内聚性等因素,会
对代码进行封装,使用配置化操作,为项目开发带来便利,这必然要求业务代码编程
范式遵循既定的约束。这种约束虽然带来了开发上的便捷,但是在一定程度上制约了
代码的可移植性。例如,在项目中使用了某个构建工具来解决项目需求,但是如果有
一天项目需要更换另一个构建工具时,代码中原有的构建工具的配置会成为冗余代
码,而且不能保证这类配置不会对新构建工具产生冲突。即便是没有产生冲突,对代
码的性能优化也是会带来一定负面影响的。工程化方案作为一种服务,应该尽量降低
对项目产生的负面影响。这是制定编程范式约束规范时最重要的考虑因素。

4.8、项目部署```js
站在前端开发的范畴来说,项目部署是指前端开发人员将构建产出的代码包部署到测
试服务器的过程,而并非是将测试完成的代码发布到生产环境的过程。在部署过程
中,要考虑目标服务器、路径信息是否与项目一一对应,并且可供负责部署到生产环
境的开发人员进行配置,部署的操作流程应尽量简单。

在部署流程中,使用命令行取代工具执行(例如FTP)本地部署,能够极大的提高部
署的速度和效率,但是这只是初级阶段的部署流程。考虑团队协作和安全方面的因
素,最佳的方式应该是搭建一个可供严格审查、队列控制、操作简化的部署平台,并
且有专人负责掌握流程进度。虽然这种搭建部署平台的方式在一定程度上减缓了整体
的部署速度,但是加强了团队协作和安全保障。

相关文章