1. 前端工程简史
1.1 前端工程师的基本素养
2008年,Google推出了全新的JavaScript引擎V8,采用JIT(实时编译)技术解释编译JavaScript代码,大大提高了JavaScript的运行性能。
REST(Representational State Transfer,具象状态传输)风格的Web服务API和SPA(Single Page Application,单页应用)风格的客户端。
REST:其实是一种组织Web服务的架构,提出了一系列架构级约束:
1)使用客户/服务器模型,客户和服务器之间通过一个统一的接口来互相通讯;
2)层次化的系统,在一个REST系统中,客户端并不会固定地与一个服务器打交道;
3)无状态,在一个REST系统中,服务端并不会保存有关客户的任何状态,也就是说,客户端自身负责用户状态的维持,并在每次发送请求时都需要提供足够的信息;
4)可缓存,REST系统需要能够恰当地缓存请求,以尽量减少服务端和客户端之间的信息传输,以提高性能;
5)统一的接口,一个REST系统需要使用一个统一的接口来完成子系统之间以及服务与用户之间的交互,这使得REST系统中的各个子系统可以独自完成演化。
前端工程师的技术栈:
1)硬技能:
HTML/CSS:DSL(Domain Specific Language,领域特定语言);
JavaScript:编程语言;
数据结构、算法、软件工程等基本知识,能够决定一个前端工程师的上限。
2)软技能:用户体验
良好的用户体验是一个Web产品的基本要素,包括但不限于以下几点:
a. 保证内容的快速展现,减少用户等待时间;
b. 保证操作的流畅度;
c. 如果是移动设备,应尽量减少设备的耗电量。
如果说按时完成了业务的所有需求是保证了“量”,那么提升产品的性能就是保证了“质”,两者缺一不可。
前端工程师不仅要求熟练地使用基本的开发技能,还必须具备性能优化的意识和技能。
3)扩展技能:Node.js
并非指的是Node.js本身,而是以Node.js为代表的Web服务器端知识。
1.2 Node.js带给前端的改革
Node.js并非是一个JavaScript框架,而是一个集成了Google V8 JavaScript引擎、事件驱动和底层I/O API,并且可使用JavaScript语言开发服务器端应用的运行环境。
同构(isomorphism)一词是数学领域的专业术语,指的是数学对象之间属性或者操作关系的一类映射。
在JavaScript开发领域研究同构的主要目的是为了将这门编程语言应用于不同的开发领域。简单讲就是令JavaScript编写的代码既可以在浏览器端工作,也可以在服务器端工作。
传统网站的渲染流程是由浏览器主动发起请求,然后服务器端生成HMTL文档后发送响应给浏览器,浏览器接到响应后将HTML文档渲染为可视网页。
随着个人终端设备和浏览器性能的不断提升,Web开发者尝试将渲染以及路由工作交给客户端,服务器端RESTFul API只提供渲染HTML所需的JSON数据,这种形态的Web应用被称为SPA(Single Page Application,单页应用)。
SPA有以下优点:
1)减轻了服务器的资源消耗;
2)与HTML文档比起来,JSON数据的体积小很多,减少了网络请求的时间消耗;
3)页面路由控制更快速灵活;
4)可以离线使用。
SPA带来的新问题:
1)“白屏时间”,浏览器需要等待JavaScript文件加载完成之后才可以渲染后续的HMTL文档内容,用户在等待的过程中页面是空白的;
2)由于客户端和服务器端编程语言不同,可能会存在一些诸如数据格式的差异,甚至路由逻辑冲突,这些问题增加了维护难度;
3)不利于常规的SEO。
与传统的服务器端渲染模式和客户端渲染的单页应用相比,同构JavaScript拥有更好的性能、可维护性以及对SEO更好的支持。
Node.js是实现同构JavaScript开发的关键。一方面,JavaScript在浏览器环境下可以执行渲染工作;另一方面,Node.js运行环境下同样可以使用JavaScript创建HTML字符串。
除了服务器端开发外,Node.js对前端最大的贡献是丰富了前端工具生态,比如Grunt、Gulp、webpack,都是由Node.js承载的。
1.3 前后端分离
前后端分离的核心是解耦:
从开发角度来讲,前后端分离的宗旨是实现并行开发,缩短开发周期;
从测试角度来讲,前后端分离令前端工程师和后端工程师更快速、精准地对问题进行定位;
从部署角度来讲,前后端分离将静态文件和动态文件分离部署并结合回滚策略,简化了部署流程,增强了应用程序的健壮性。
前后端分离策略是制定前端工程化解决方案的指导方针之一;前端工程化的最终目的之一便是实现更合理、更便利的前后端分离开发环境。如果将前后端分离策略比喻成建筑设计图,那么前端工程化方案就是按照这张设计图进行具体建设的。
1.4 前端工程化
从开发角度衡量工程化主要体现在“快”:
工程化方案的核心目标之一就是在保证质量的前提下,尽可能提高产品的开发速度。
从测试角度衡量工程化主要体现在“快”和“准”:
测试的“快”体现在前端工程师和服务器端工程师并行开发完成之后的集成测试阶段,工程化要解决的就是尽量减少低级的逻辑错误,降低集成测试阶段消耗的时间成本;
测试的“准”体现在集成测试阶段对问题的准确定位,通过明确责任人,对测试出现的问题进行快速准确的定位。
从部署角度衡量工程化主要体现在“稳”:
部署并不是简单地把文件“放到”线上就可以了,还需要考虑用户客户端的缓存是否影响了新版本的展现、考虑测试用例没有覆盖100%情况下的危机处理、考虑不同地区开放不同版本等。
前端工程化的第一步:加入构建流程
构建流程可以确保前端工程师能够使用有助于提高开发和维护效率的框架、规范进行源代码的编写,构建还具备图片压缩、自动生成CSS Sprites等功能,进一步减少了烦琐的人工操作。
前端工程化的第二步:加入本地开发服务器
本地开发服务器并不是工具,而是一个真正意义上的Web服务。本地服务器最典型的应用是Mock服务,通过提供模拟接口和数据解决前端JavaScript对数据API的依赖问题,从而实现前后端并行开发,前提是前后端工程师在进行开发阶段之前需要协商制定接口API的详细规范。
本地服务器须具备以下功能:
1)Mock服务,如果团队具备统一的云Mock平台,本地服务器可以不提供Mock服务,如果需要支持SSR,则必须提供本地Mock服务;
2)支持SSR(Server Side Render,服务器端渲染),前提是本地服务器与线上服务器使用相同的编程语言;
3)动态构建,浏览器自动刷新。
前端工程化的第三步:静态资源和动态资源分离部署
优化部署的基本原则是,确保单方问题的修复不需要调动多方资源,具体的解决方案就是静态资源与动态资源分离部署。
前端渲染的优点:
1)前端掌控路由,与传统的服务器端路由相比用户体验更佳;
2)可移植、可离线使用;
3)服务器端提供的是干净的数据接口,具备高度的可复用性;
4)HTML资源作为静态资源,易于部署;
5)前端工程师与后端工程师可以使用Git、SVN等工具分别维护独立的源代码,无须耦合。
前端渲染的缺点:不利于SEO。
加入静态资源与动态资源分离部署功能后,一方面提高了部署的效率,另一方面也提高了Bug的修复效率。
不论前端工程化的功能如何完备,规范如何严谨,需要谨记的是,前端工程化必须是整个Web工作流中间的一个子集方案。前端工程化最终的完美形态,必然与整体工作流结合,作为持续集成方案中的一环。
1.5 工程化方案架构
目前市场上流行的前端工具大体分为3类:
1)工作流管理工具:比如Grunt、Gulp;
2)构建工具:比如webpack、rollup;
3)整体解决方案:比如FIS、WeFlow。
以本地工具链形态的前端工程化方案Boi为例,整体架构如图:
Boi是一款开源的前端工程化方案,可以在GitHub(https://github.com/boijs/boi)中获取源码。