浅析新版“启嘉网” 前端项目架构

@Author 郭奇奇
@Date 2016-12-7

本文章基于以下CC协议知识共享:署名(BY)-非商业性使用(NC)-禁止演绎(ND)


本文主要以“启嘉网”项目为样本,简单讲解一些前端开发流程优化中涉及到的技术,包含:Webpack,Grunt,Babel,NightWatch,Mocha,等等。

本文章日后可能会有修改和更新,将会在此记录。
2018年02月02日:启嘉网前端架构设计分享

随着移动端与轻应用的兴起,前端工程师的职能早已不是简单的切图搭页面了,前端的开发技术也变得越来越复杂,从HTML,CSS,JS到语义化标签,硬件加速,模块化,数据驱动。JS正逐步从一个运行在浏览器的脚本语言走向企业级的开发语言。本文就我在校实习一年多的经历,总结一下对于前端技术的学习的过程。

自去年我加入到“启嘉网”项目的前端开发与UI设计中,总共经历过3次较大的版本迭代和重构。在每一版的更新中,开发组对于技术的不断追求,使得启嘉网整体的设计风格和技术选型都有非常大的变化。一年间开发组的每个人也都有很大的进步。

以前端开发来看,在最新的这一版之前,经历了:纯HTML5 + CSS3 + JavaScript 和 Grunt项目自动构建工具 这两个过程。由于功能的不断迭代,项目的代码越来越多,文件越来越大。传统的前端开发模式(纯HTML5、CSS3、JS)暴露出了诸多问题:项目难以维护,开发成员无法配合,页面性能低下。而第二个阶段是暑假时进行的,当时工作上还有一些课程和设计的任务。所以,虽然加上了Grunt项目构建工具,但是由于比较忙,我在前端开发上投入的精力不多,导致开发进行的并不理想。

最近项目整体已经趋于稳定,也没有新需求,可以静下心来专心的对项目进行优化了。下面会列出“启嘉网”项目的前端开发中所用到的技术,并解释其意义和理由。

模块化开发与自动构建


使用开发者工具打开当前的“启嘉网”首页,可以看到静态资源文件(HTML,CSS,JS)总共发起了16条加载请求。并且资源文件未使用缓存,全部为200状态。

浅析新版“启嘉网” 前端项目架构_第1张图片
首页资源文件加载

这样导致的问题就是:

  1. 大量用户访问的情况下,并发请求过多,降低服务器效率。
  2. 零碎的小文件并发请求,在与服务器连接时耗费时间。
  3. 重复加载静态文件,浪费服务器资源。

其次,还可以看出页面代码与逻辑代码分离混乱。导致后期极难维护,开发人员也不好配合。

JS模块化

模块化的意思是:比如,前端页面效果可以在 A.js 文件中编写,而 Ajax 交互可以在 B.js 中编写,而某些功能所有页面都会用到,则单写一份 C.js,并且,A.js 可以引用 C.js ,B.js 也可以引用 C.js。如此一来,页面的代码就可以分割成一份一份的小文件,并且某些文件还可以重复利用。

虽然 ES6 已经开放了模块化的规范。但是目前还没有任何浏览器支持。所以只能使用第三方框架解决,比如:RequireJS,SeaJS,Webpack等等。这些框架都很优秀,但是由于 RequireJS 和 SeaJS 年代比较久远,实现的功能很单一。而 Webpack 除了模块化,还包含很多其他的特性 —— 模块打包、压缩混淆、Module Loader 等。并且在现在也相对主流,社区也很活跃。所以“启嘉网”选择了Webpack。

代码自动构建

成功进行模块化后,如果每个JS模块在页面中都单独加载的话,又会造成并发数上升的问题。所以根据前端优化原则,应该尽可能的将静态文件合并成一个单文件。而这就是自动构建工具的意义,自动处理所有重复单一的任务,节省开发人员的时间。

浅析新版“启嘉网” 前端项目架构_第2张图片
自动构建文件追加HASH值
浅析新版“启嘉网” 前端项目架构_第3张图片
自动将小于10KB的图片转到Base64编码

结合 Grunt 和 Webpack,整个项目可以自动清理编译目录;打包、压缩、混淆JS代码;提取不会变动的公用库并打包,使其100%命中缓存;然后自动为打包文件重命名,追加hash值,解决项目升级部署时导致的缓存问题;自动在HTML页面中追加静态资源引用地址;自动将小于10kb的图片转成Base64格式,减少请求数;等等。

Webpack Module Loader

这里应该要拿出来单说一下,Webpack 的核心思想就是把一切静态资源都当成模块,不管是CSS,LESS,JS,图片,都可以通过require的方式引用文件,写在JS中。其实最开始我考虑的,是这样写破坏了原生的JS写法,对require的过度依赖,导致后期想切换框架的时候产生问题。不过,谁让require用起来太™爽了,所以我们依然选择使用 Webpack。

如此一来,开发组再也不用来回在 HTML,CSS,JS 的编辑器页面间来回切换了,写好后直接在JS中require即可。另外一点就是 Webpack 可以设置路径的别名,比如一个CSS文件,相对于某个文件的路径是:“../../css/index.css”。那么通过设置别名,我们再JS中引用,只需写:require("css/index.css")即可。

Babel 转译器

JavaScript 是基于 ECMA Script 语法规范而来的。目前浏览器普遍支持的是 ECMA2015(ECMA-262 Edition 5.1) 规范。而在 2015年6月份 ,新版本的 ECMAScript 规范(ES6)就已经推出了第一个版本。虽然过了一年多,各个浏览器的支持还是很不好(笑)。但是技术总是要推陈出新的,为了“启嘉网”的未来发展,为了更优秀的技术,开发组决定还是使用 ES6 进行编码。而兼容问题,则交给 Babel 转译器去解决。

ES6 规范很大一部分是“语法糖”。也就是改进了 ES5 中,很不舒服的一些写法。实际上,ES6 中的很多特性的写法,都是可以转写成 ES5 的。所以 Babel 也是基于这个原理工作的。比如:

function someES6() {
    var some = "Hello";
    var ES6 = "World";
    return { some, ES6 }; // 等价于 return {some:"Hello",ES6:"World"};
}

let data = someES6();

alert(`${data.some} ${data.ES6}`); //等价于 alert(data.some+" "+data.ES6);
浅析新版“启嘉网” 前端项目架构_第4张图片
优雅的写代码

热加载

调试页面是一件很痛苦的事情,修改一下代码,就要切换到浏览器刷新查看。所幸 Webpack 提供了 webpack-dev-server 这个插件,可以检测到代码发生变动时,自动刷新浏览器。极大的方便了开发人员(前提是你要有多个显示屏,效果更佳)。

浅析新版“启嘉网” 前端项目架构_第5张图片
Biger Than Biger

单元测试与E2E


当JS模块越来越多的时候,随之而来的另一个问题就是,当你修改了其中一个的代码,怎么保证不影响其他的模块?所以,单元测试的意义就是,向一个模块中模拟输入数据,检查结果是否符合预期。

在前端中,单元测试框架可以使用 Karma 或者 Mocha,不过我最心水的是前端的E2E(End to End,端到端)测试框架 —— NightWatch。它可以模拟用户在页面上的点击,拖动,滚动,等等一系列操作。有了它就不用自己打开浏览器去手动测试了。简直屌爆了有没有。

WebGL


淘宝在双十一的时候,制作了一个非常酷炫的H5页面(地址忘了- -)便是基于 WebGL 技术的。这项技术可以让浏览器展现 3D 画面,实现更多意想不到的效果。虽然设计图我还没设计好,不过,我一定会在新版本的“启嘉网”中,或多或少的引入这项技术,基于 Three.js 框架。

总结


至此,大概说完了“启嘉网”整体的前端架构(针对开发流程优化方面),也就是想方设法的让开发人员更♂爽的故事,⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄。虽然很多技术细节没有说到(比如:图片自动压缩,HTTP缓存技术,硬件加速,等),这些内容可以通过百度自己学习、了解。

以及“启嘉网”的一些前端框架选择(比如:jQuery,VUE,CSS LESS,等)也没有提到。这些内容会在新版本开发完成后,再单独写一篇文章详细说明。

这篇文章仅仅是对最近的工作做个总结和笔记(记性不好,搭建完的环境我自己都忘了我干啥了,笑~)。感谢大家阅览,求赞、求转发、求打赏。。。

你可能感兴趣的:(浅析新版“启嘉网” 前端项目架构)