自动化构建 是区分二线前端团队和一流前端团队的重要因素,只有工程化前端过程,才能让前端程序猿摆脱手工作坊式的开发,升级为前端工程师。
2015年的架构主要围绕"自动化构建"展开。我们选用了 Gulp( gulpjs 商业网/) 作为前端构建系统,串起标准构建过程:
这样,就可以将_日常工作_交给机器去做,甚至开发者无需懂得细节也可以应用先进的前端优化技巧。
事实上,这个列表还可以扩充:
完全可以满足团队进化的需求。
基于构建系统,我们创建了纯前端的组件框架:QBao-Web

在Gulp中,我们加入了两个定制的任务:
所以说,2015年我们的前端框架,是围绕着"自动化构建"建立的。
前后端分离是这两年很热门的提法。
随着HTML5/CSS3广泛推广,前端框架不断进化,前端开发越来越专业化,自然想要摆脱后端的束缚,NodeJS的出现,也让前端工程师看到更多的可能。同时后端工程师也希望更多地专注于后台业务逻辑,而不是页面性能或是多浏览器适配。所以前后端分离,就是让“专业的人做专业的事”。
前后端分离不是一定要采用NodeJS做服务器,也不是一定要采用AngularJS,相反的,盲目引入新技术很容易让项目陷入困境,让开发人员不知所措,最好能采用一些温和的方式一步步来。

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- build:css ../components/components.min.css -->
<!-- components:css -->
<!-- endinject -->
<link rel="stylesheet" href="../common/styles/base.css">
<link rel="stylesheet" href="styles/index.css">
</head>
<body>
@@include('../components/site-top/site-top.html')
@@include('../components/site-header/site-header.html')
<div id="banner" class="container">
<div class="main container clearfix">
<div id="auction-list" class="list">
<div class="right-side">...
...
@@include('../components/site-footer/site-footer.html')
<script id="banner-template" type="text/x-handlebars-template">
{ {#each list} }
<div>
<a href="{ {target} }">
<img src="{ {path} }" />
</a>
{ {/each} }
</script>
<script id="auction-list-template" type="text/x-handlebars-template">
<ul>
{ {#each list} }
<li class="item">
<p class="name">{ {product.name} }</p>
<section class="content">
<img class="picture" src="{ {picture} }" />
<div class="price-bar">
<div class="value">
<img src="images/rmb-icon-gray.png" />
<p class="number">{ {value} }</p>
<p class="note">市场价</p>
...
<footer>
<ul>
<li>
<p><span>{ {register} }</span>人</p>
<p class="note">报名人数</p>
</li>
...
</ul>
</footer>
</li>
{ {/each} }
</ul>
</script>
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<script src="../bower_components/handlebars/handlebars.min.js"></script>
<!-- components:js -->
<!-- endinject -->
<script src="scripts/index.js"></script>
</body>
</html>
这是一个很典型的页面,雷拍列表。
由于没有后台服务器为我们组装页面,我在这里采用了自定义语法来引入公共控件,比如页头和页尾。
@@include('../components/site-top/site-top.html')
@@include('../components/site-footer/site-footer.html')
这不是标准的html语法,所以这个页面也无法直接在浏览器中加载,需要使用NodeJS预编译成HTML发布。
这里的NodeJS作为编译工具出现,而不是服务器,理论上也可以使用NodeJS原配的Jade模板语言来完成,不过需要引入一个不那么像HTML语法的生成器,不是很爽。
有了这种设计,我们就不需要将公用元素在每个页面中重复,可以最大化地复用,也能方便地统一修改。
动态元素由 HandlerBars 模板生成,比如这个 Banner:
<script id="banner-template" type="text/x-handlebars-template">
{ {#each list} }
<div>
<a href="{ {target} }">
<img src="{ {path} }" />
</a>
{ {/each} }
</script>
选用 HandlerBars,一是因为它的语法很接近 HTML,二是因为它非常快。
数据获取通过 jQuery 的 ajax 函数:
var loadBanner = function() {
var source = $('#banner-template').html();
var template = Handlebars.compile(source);
$.get('http://localhost:3000/banners/54c98efa2d2c4b7517e8c63f').done(function(resp) {
var urlList = $.map(resp.pictures, function(picture) {
picture.path = 'http://localhost:3000/uploads/' + picture.name;
return picture;
});
var html = template({
list: urlList
});
$('#banner').append(html);
});
};

模块化地组织目录结构,可以方便地分人员开发和负责。

使用 Gulp 搭建自动化构建环境,除了前述公用元素插入,自动化构建还支持:
优点
缺点
随着项目越来越大,页面越来越多,web2.0的构建系统慢慢吃力起来,动辄要10分钟才可以构建一遍,而且要上传到构建服务器构建,成功后再从服务器上下载下来,构建周期太长,已经违反了架构的初衷。
针对这一情况,我们推出了web2.1框架,主要优化如下:
优化仍然是围绕着"自动化构建"开展的。
mobile的目录结构和web2.0是一样的,意味着构建过程也是一样的,主要区别如下:
mobile2.1对于mobile的改变主要也是构建系统的优化:
QBao-Web 和 QBao-Mobile 的主要目的是规范化前端开发过程,同时推动前后端分离的工作模式,而QBao-Admin更加关注前端框架后续的发展,尝试了很多新的第三方类库和先进的理念。

如图所示,分层管理、控件抽象、业务分离,QBao-Admin 展现出来一个现代的前端架构应有的特性,将一些本来是后端的逻辑前移,让后端更加专注于业务,让前端处理路由、渲染,各司其职,各取所长。

在 QBao-Admin 中我们使用 ReactJS 作为展示框架,使用 Reflux( github /reflux/refluxjs) 的单向数据流控制业务逻辑,使用 Webpack 作为打包工具。
这套方案是后述 QBao-H5App 和 QBao-Universal 框架的基础。

