自有前端工程师这个称谓以来,前端的发展可谓是突飞猛进。相比较已经很是成熟的其余领域,前端虽是后起之秀,但其野蛮生长是其余领域不能比的。虽然前端技术飞快发展,可是前端总体的工程生态并无同步跟进。目前绝大多数的前端团队仍然使用很是原始的“切图(FE)->套模板(RD)”的开发模式,这种模式下的前端开发虽然说不是刀耕火种的原始状态,可是效率很是低下。php
前端的工程化问题与传统的软件工程虽然有所不一样,可是面临的问题是同样的。咱们首先回顾一下传统的软件开发流程模型:css
上图中的运行和维护并非串行关系,也并不是绝对的并行关系。维护贯穿从编码到运行的整个流程。html
若是说计算机科学要解决的是系统的某个具体问题,或者更通俗点说是面向编码的,那么工程化要解决的是如何提升整个系统生产效率。因此,与其说软件工程是一门科学,不如说它更偏向于管理学和方法论。前端
软件工程是个很宽泛的话题,每一个人都有本身的理解。以上是笔者我的的理解,仅供参考。node
具体到前端工程化,面临的问题是如何提升编码->测试->维护阶段的生产效率。python
可能会有人认为应该包括需求分析和设计阶段,上图展现的软件开发模型中,这两个阶段具体到前端开发领域,更恰当的称谓应该是功能需求分析和UI设计,分别由产品经理和UI工程师完成。至于API需求分析和API设计,应该包括在编码阶段。程序员
要解决前端工程化的问题,能够从两个角度入手:开发和部署。es6
从开发角度,要解决的问题包括:web
这两个问题的解决方案有两点:npm
从部署角度,要解决的问题主要是资源管理,包括:
要解决上述问题,须要引入构建/编译阶段。
开发规范的目的是统一团队成员的编码规范,便于团队协做和代码维护。开发规范没有统一的标准,每一个团队能够创建本身的一套规范体系。
值得一提的是JavaScript的开发规范,尤为是在ES2015愈来愈普及的局面下,保持良好的编码风格是很是必要的。笔者推荐Airbnb的eslint规范。
不少人会混淆模块化开发和组件化开发。可是严格来说,组件(component)和模块(module)应该是两个不一样的概念。二者的区别主要在颗粒度方面。《Documenting Software Architectures》一书中对于component和module的解释以下:
A module tends to refer first and foremost to a design-time entity. ... information hiding as the criterion for allocating responsibility to a module.
A component tends to refer to a runtime entity. ... The emphasis is clearly on the finished product and not on the design considerations that went into it.
In short, a module suggests encapsulation properties, with less emphasis on the delivery medium and what goest on at runtime. Not so with components. A delivered binary maintains its "separateness" throughout execution. A component suggests independently deployed units of software with no visibility into the development process.
简单讲,module侧重的是对属性的封装,重心是在设计和开发阶段,不关注runtime的逻辑。module是一个白盒;而component是一个能够独立部署的软件单元,面向的是runtime,侧重于产品的功能性。component是一个黑盒,内部的逻辑是不可见的。
用通俗的话讲,模块能够理解为零件,好比轮胎上的螺丝钉;而组件则是轮胎,是具有某项完整功能的一个总体。具体到前端领域,一个button是一个模块,一个包括多个button的nav是一个组件。
模块和组件的争论由来已久,甚至某些编程语言对二者的实现都模糊不清。前端领域也是如此,使用过bower的同行知道bower安装的第三方依赖目录是bower_component
;而npm安装的目录是node_modules
。也不必为了这个争得头破血流,一个团队只要统一思想,保证开发效率就能够了。至因而命名为module仍是component都无所谓。
笔者我的倾向组件黑盒、模块白盒这种思想。
随着web应用规模愈来愈大,模块/组件化开发的需求就显得愈来愈迫切。模块/组件化开发的核心思想是分治,主要针对的是开发和维护阶段。
关于组件化开发的讨论和实践,业界有不少同行作了很是详细的介绍,本文的重点并不是关注组件化开发的详细方案,便再也不赘述了。笔者收集了一些资料可供参考:
严谨地讲,构建(build)和编译(compile)是彻底不同的两个概念。二者的颗粒度不一样,compile面对的是单文件的编译,build是创建在compile的基础上,对所有文件进行编译。在不少Java IDE中还有另一个概念:make。make也是创建在compile的基础上,可是只会编译有改动的文件,以提升生产效率。本文不探讨build、compile、make的深层运行机制,下文所述的前段工程化中构建&编译阶段简称为构建阶段。
在讨论具体如何组织构建任务以前,咱们首先探讨一下在整个前端工程系统中,构建阶段扮演的是什么角色。
首先,咱们看看目前这个时间点(2016年),一个典型的web先后端协做模式是什么样的。请看下图:
上图是一个比较成熟的先后端协做体系。固然,目前因为Node.js的流行开始普及大前端的概念,稍后会讲述。
自Node.js问世以来,前端圈子一直传播着一个词:颠覆。前端工程师要借助Node.js颠覆以往的web开发模式,简单说就是用Node.js取代php、ruby、python等语言搭建web server,在这个颠覆运动中,JavaScript是前端工程师的信心源泉。咱们不讨论Node.js与php们的对比,只在可行性这个角度来说,大前端这个方向吸引愈来愈多的前端工程师。
其实大前端也能够理解为全栈工程师,全栈的概念与编程语言没有相关性,核心的竞争力是对整个web产品从前到后的理解和掌握。
那么在大前端模式下,构建又是扮演什么角色呢?请看下图:
大前端体系下,前端开发人员掌握着Node.js搭建的web server层。与上文提到的常规前端开发体系下相比,省略了mock server的角色,可是构建在大前端体系下的做用并无发生改变。也就是说,不管是大前端仍是“小”前端,构建阶段在两种模式下的做用彻底一致,构建的做用就是对静态资源以及模板进行处理,换句话说:构建的核心是资源管理。
前端的资源能够分为静态资源和模板。模板对静态资源是引用关系,二者相辅相成,构建过程当中须要对两种资源使用不一样的构建策略。
目前仍然有大多数公司将模板交由后端开发人员控制,前端人员写好demo交给后端程序员“套模板”。这种协做模式效率是很是低的,模板层交由前端开发人员负责可以很大程度上提升工做效率。
静态资源包括js、css、图片等文件,目前随着一些新规范和css预编译器的普及,一般开发阶段的静态资源是:
构建阶段在处理这些静态文件时,基本的功能应包括:
以上提到的几个功能能够说是为了弥补浏览器自身功能的缺陷,也能够理解为面向语言自己的,咱们能够将这些功能统称为预编译。
除了语言自己,静态资源的构建处理还须要考虑web应用的性能因素。好比开发阶段使用组件化开发模式,每一个组件有独立的js/css/图片等文件,若是不作处理每一个文件独立上线的话,无疑会增长http请求的数量,从而影响web应用的性能表现。针对诸如此类的问题,构建阶段须要包括如下功能:
以上几个功能除了压缩是彻底自动化的,其余两个功能都须要人工的配置。好比为了提高首屏渲染性能,开发人员在开发阶段须要尽可能减小同步依赖文件的数量。
以上提到的全部功能能够理解为工具层面的构建功能。
以上提到的构建功能只是构建工具的基本功能。若是停留在这个阶段,那么也算是个及格的构建工具了,但也仅仅停留在工具层面。对比目前较流行的一些构建产品,好比fis,它具有以上所得的编译功能,同时提供了一些机制以提升开发阶段的生产效率。包括:
咱们也能够将上面提到的功能理解为平台层面的构建功能。
模板与静态资源是容器-模块关系。模板直接引用静态资源,通过构建后,静态资源的改动有如下几点:
其实url包括文件名的改动,之因此将二者分开论述是为了让读者区分CDN与构建对资源的不一样影响。
对于模板的构建宗旨是在静态资源url和文件名改变后,同步更新模板中资源的引用地址。
如今有种论调是脱离模板的依赖,html由客户端模板引擎渲染,简单说就是文档内容由JavaScript生成,服务端模板只提供一个空壳子和基础的静态资源引用。这种模式愈来愈广泛,一些较成熟的框架也驱动了这个模式的发展,好比React、Vue等。但目前大多数web产品为了提升首屏的性能表现,仍然没法脱离对服务端渲染的依赖。因此对模板的构建处理仍然颇有必要性。
具体的构建策略根据每一个团队的状况有所差别,好比有些团队中模板由后端工程师负责,这种模式下fis的资源映射表机制是很是好的解决方案。本文不讨论具体的构建策略,后续文章会详细讲述。
模板的构建是工具层面的功能。
构建能够分为工具层面和平台层面的功能:
一个完整的前端工程体系应该包括:
开发规范和组件化开发面向的开发阶段,宗旨是提升团队协做能力,提升开发效率并下降维护成本。
构建工具和平台解决了web产品一系列的工程问题,旨在提升web产品的性能表现,提升开发效率。
随着Node.js的流行,对于前端的定义愈来愈宽泛,在整个web开发体系中。前端工程师的角色愈来愈重要。本文论述的前端工程体系没有涉及Node.js这一层面,当一个团队步入大前端时代,前端的定义已经不只仅是“前端”了,我想Web工程师这个称号更合适一些。
以前跟一位前端架构师讨论构建中对于模块化的处理时,他提到一个颇有意思的观点:所谓的压缩打包等为了性能作出的构建,实际上是受限于客户端自己。试想,若是将来的浏览器支持大规模并发请求、网络延迟小到微不足道,咱们还须要压缩打包吗?
诚然,任何架构也好,策略也好,都是对当前的一种解决方案,并非一条条铁律。脱离了时代,任何技术讨论都没有意义。
学习前端的同窗们,欢迎加入前端学习交流群
前端学习交流QQ群:461593224