如何构建前端代码

jopen 8年前
 

基本认识

开发环境和线上环境的区别

在很久以前,前端的部署其实比较简单,开发环境下,静态资源往服务器上面一扔就ok了,如果考虑下优化或者代码保护,也只是加一个代码压缩和混淆。没错,刚入行的时候我就是这么干的。。。

但是随着前端复杂度的发展,上面的做法已经无法满足需求了,特别是AMD,CMD概念的引入,打包合并就变成一项基本工作了。

举一个requirejs的例子,在一个复杂点的前端系统中,你能想象不打包直接上线吗,那样换来的可能就是打开首页就需要download几十个甚至上百个模块资源,这种行为是对网络资源的一种无谓消耗。所以对应requirejs有个r.js,就是专门消灭这种无谓请求消耗的,它做的事情也比较简单,按照一定规则,把各种模块合并成一个,这样在上线是一次请求就能download需要的所有js。

开发环境代码和线上代码区别

首先大家可以在构建时取消类似压缩,混淆这几部,可以观察下,构建完成后的代码,会和开发时你所写的有差别,开发环境的代码都经过了编译处理,根据一定的规则重新编译过。

举一个例子,我们在使用css3时,如果去自己写样式去适配chorme,safari,opera等等会累死。但是我们按照一个规则写一个,在构建时,代码自动做补全,是不是就很方便,能提高不少效率。

再举个例子,现在比较前沿的已经在开发环境下使用ES6了,但是想要在浏览器端直接运行还需要一段日子,但是没事,我们有Babel之类的工具,可以在编译时实现ES6到ES5的代码转换。这种用法我还没有用过,但是通过构建,我们可以用于尝试一些新的东西。提前做一些技术积累。

前端工程化核心环节

从前面两点大家应该能看出构建这一步的重要性了吧,可以说需要做到前端工程化,提高开发效率等,构建编译这一个步骤绝对是核心步骤之一。他的角色不逊色于搭建service,项目脚手架等等

具体举例

百度前端不仅有个fis(前端集成解决方案),还有一个edp,也是一个前端集成解决方法,主要是百度商业体系的前端在使用。由于我们一直在使用edp,所以下面用edp举例去了解下前端构建

下面介绍一下我们自己系统中的一些使用

  1. 首先是js模块的合并,我们会按照首屏加载和可以懒加载的功能划分,将模块合并成整体,这样就避免了散文件的出现。首先散文件是有害处的,第一是,散文件可能没有版本号的区分,这样因为缓存导致bug;第二是散文件会严重拖慢性能,因为很多散文件不仅消耗请求资源,而且是在串行消耗。

  2. 将js用到的模板的合并,目的也是减少无谓的请求。

  3. 将less转换成css进行合并

  4. 将js文件压缩处理

  5. 将合并后的文件进行加上文件MD5版本号处理,MD5的目的就是基于文件内容解析出版本号,这样如果某个模块没有变更过,可以一直使用缓存,提高性能。

  6. 将合并后并且包含MD5的文件的path更新到首页html的require的config中

  7. 修改文件引用对应的path,因为类似于js引用的模板和css都需要更新到打包合并的path上

  8. 清理输出时的无用文件

  9. 添加版权信息等等

上面是一个基本流程,如果有特殊的需求,可以继续添加处理模块。例如想引入reactjs,如果是构建时打包的话,我们肯定不希望上线的代码里面有一个browser.min.js文件,这样不仅增加了静态资源,而且增加了一个jsx翻译处理。那么我们可以在构建时增加一个jsx2js的步骤,这样就达到了,开发使用jsx,但是发布上线时,自动处理成了js代码。

关于性能优化

这种构建处理,我理解出发点都是从性能角度考虑的。

对于一线的业务开发过程,我们期望的是高效的开发业务,并不能把性能等等要求强加到业务开发中,不然我们业务开发是低效的,而且,随着性能优化策略的变更,我们无法随意的在业务中修改代码及时配合,就算是有人力修改,也可能导致bug。

所以将构建和业务解耦也是很关键的,只要业务开发符合某个规范,我们可以根据性能优化的点随时更新优化策略,构建代码的差别也是仅仅体现在性能上,而不会延生到业务中。

注意事项

大家可以看看前面几篇文章《如何避免工程效率陷阱》,《如何在大公司中成长》我们在拥抱前端工程化时,不要停留在使用阶段,也需要花点时间研究下原理,不然就很容易被工程了,因为你要相信未来前端的工程化只会让你的业务开发更加简单,关心的东西更少。