糯米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%}
<div class="header">
<span class="header-title">下載手機版</span>
</div>
{%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出品的神器,能解決我們遇到的大部分問題。
下一篇來說說我們的具體實踐過程