糯米PC是一个典型的PC站点页面,包含一个团购网站所需要的全部功能,从网站开发角度来讲,是一个典型的website
开发模式。
该网站的前端架构是以百度内部的前端开发框架FIS为基础搭建的。经过了N帮人的交接,现在的代码变得难以维护,所以近期打算对糯米的PC进行一次重构。
重构的目的主要为以下几点:
- 解决现有的问题
- 提升开发效率
- 提高代码的可维护性和拓展性
现状梳理
先来看看现在代码遇到的几个棘手的问题吧:
没有合理的模块化
这个应该是代码编写的问题,而不是框架的问题。一个典型有问题的js代码结构如下:
var xxx = require('xxx'); // 拿到依赖
$(function () {
function a () {
// do something
}
function b () {
// do something
}
function init() {
a();
b();
}
init();
});
看到这个也是醉了,首先因为经过FIS
的处理之后,js
代码都是在body
标签之前加载的,所以大部分的jquery
的ready函数都是没有意义的。而且代码没有以模块的方式给外部提供相应的接口来进行调用和处理,对于业务逻辑之间相互调用和测试十分不便。
前端代码和后端模板耦合
这应该是FIS
的特性引起的,FIS有一个widget
的功能,利用它可以在smarty
之间互相调用每个组件,同时加载相应的静态资源。代码实例如下:
{%function name="header" isWanda=false%}
下载手机版
{%require name='common:widget/header/sug/sug.less'%} // 自动加载less
{%script%}
require.async([
'common:widget/header/header.js' // 调用js
]);
{%/script%}
{%/function%}
//调用的时候
{%widget call="header" isWanda="true"%}
在一个模板片段的包含了html
、js
、css
三种资源的关系, 这可以方便的在其他调用这个widget,而不需要管理它的css
和js
,这是它的一个优点。
但是随着开发的业务逻辑越来越多,会发现越来越多的业务逻辑会放在smarty
中直接完成。。。。后来发现大部分业务逻辑都是php
写的有木有~~~新来的同学就会抱怨一句:“我是来写前端的,怎么叫我写php!!!”。更让人不爽的是,如果页面有异步更新,比如ajax调用来更新结构,为了复用逻辑代码,只能叫后端直接去渲染smarty得到完整的html片段,然后塞进页面中,前端很难在数据做一些必要的二次修改。
同时smarty业务逻辑一旦出现异常(比如后端返回的数据接口不对或者编写php语法的有坑引起的),前端无法对异常进行相应的处理,导致部分页面可能直接无法显示。
调试困难
由于上面所说,大量组件和业务代码充斥在smarty中,前端无法更好的利用浏览器进行调试,只能去看php的错误日志。。。这种情况下,整个开发过程变得十分被动(虽然我们建议一个前端可以简单能查看后端的错误日志)。
代码难以测试
由于smarty承担了大部分的职责,各种前端测试框架都没用了鸟~~
解决之道
经过前面简单的梳理,可以发现糯米的架构是跟整个社区的前端开发趋势是有所背离的。以下是具体的修改思路:
代码模块化管理
这个没什么好说的,首先,我们去除了FIS
自带的包管理机制,采用社区常用的AMD
或者CommonJS
作为模块管理的形式,每个模块提供相应的初始化接口。
利用bower
或者npm
作为包管理工具。
以JS为中心
所有的业务逻辑全部采用JS
来编写,后端模板只用来承载相应的首屏信息。同时要求后端人员编写前端开发所需的数据接口形式的数据。对于各个业务逻辑之间通信采用相应的接口,或者以全局事件的方式进行通信。
全站组件形式组织
FIS的widget给了我们对于组件的编写一定的启发,我们r认为组件是以html
、js
、css
三种资源结合起来的
因此思考了组件的基本结构如下:
├── search
│ ├── main.js
│ ├── main.less
│ ├── main.tpl
│ ├── mock.json
│ └── suggestion.html
上面显示的是一个基本的widget结构,包含所有的资源。我们通过js来管理less,其中suggestion.html
这个我们用来处理异步功能的前端模板片段,通过前端模板引擎可以方便地在js中调用。如何实现各种资源的无缝调用,我会在下篇的具体实践中讲一下。
效果收益
总结一下,收益有以下几点:
- JS负责资源管理和业务逻辑,给予前端最大的灵活度,维护性加强
- 通过
karma
等前端开发框架,方便对新代码进行测试 - 因为保留
FIS
原有的上线、部署功能,提高前端工程化效率
待解决的问题
后端模板去留
后端模板对于前端最好的方式当然是不再使用。基于对于糯米现有的业务形式,需要考虑SEO,首屏速度等条件制约下,还是暂时保留了,但是我们通过了smarty4js
这个同事编写的npm
模块,最大程度地减少了编写同一份模板的工作。
资源打包
因为去除了FIS
的大部分功能,我们必须通过另外一个途径来实现JS对各个资源的调用问题,对网上的许多解决方案进行了调研,发现webpack这一facebook出品的神器,能解决我们遇到的大部分问题。
下一篇来说说我们的具体实践过程