baidu yogurt前端集成解決方案
yogurt 是基于 fis 擴(kuò)展針對服務(wù)端為 express.js 的前端集成解決方案。
在閱讀此文檔之前,希望你最好對 fis 有一定的了解。此工具主要負(fù)責(zé)前端編譯與環(huán)境模擬,讓你更專注、更快速地開發(fā)前端部分,關(guān)于后端 express 框架部分,請查看 yog。
特點(diǎn)
-
擴(kuò)展 swig 模板引擎,提供易用的
html、head、body、widget、script、style等等標(biāo)簽?;谶@些標(biāo)簽后端可以自動(dòng)完成對頁面的性能優(yōu)化。 -
基于
widget標(biāo)簽,可以輕松實(shí)現(xiàn)讓widget以 BigPipe 模式渲染,詳情請查看這里。 -
提供便利的環(huán)境、數(shù)據(jù)和頁面模擬。tpl 自動(dòng)與 json 數(shù)據(jù)文件關(guān)聯(lián),本地就能預(yù)覽線上效果。
-
此工具負(fù)責(zé)生成 tpl 和關(guān)聯(lián)的靜態(tài)資源。后端只需關(guān)注頁面邏輯,數(shù)據(jù)獲取以及渲染模板即可,無需關(guān)心前端領(lǐng)域。
快速開始
# 安裝 yogurt 到全局npm install -g yogurt# 安裝 lights 如果你還沒安裝過。npm install -g lights# 下載 demo.lights install yogurt-demo# 進(jìn)入 yogurt-demo 目錄, release 后就可以預(yù)覽了。cd yogurt-demo yogurt release yogurt server start
目錄規(guī)范
├── page # 頁面 tpl ├── static # 靜態(tài)資源 ├── widget # 各類組件 ├── test # 數(shù)據(jù)與頁面模擬目錄 ├── fis-conf.js # fis 編譯配置 ├── server.conf # 測試頁面轉(zhuǎn)法規(guī)則配置文件
page 目錄
所有頁面級別的模板文件,放在此目錄。此tpl 可以直接在瀏覽器中預(yù)覽。比如 page/index.tpl 可以通過 http://127.0.0.1:8080/{{ namespace }}/page/index 訪問。 其中 {{ namespace }} 為此項(xiàng)目的名稱。
需要強(qiáng)調(diào)的的是,模板引擎采用的是 swig, 可以采用模板繼承機(jī)制來實(shí)現(xiàn)模板復(fù)用。
static 目錄
用來存放所有靜態(tài)資源文件,css, js, images 等等。如:
├── css │ ├── bootstrap-theme.css │ ├── bootstrap.css │ └── style.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff └── js ├── bigpipe.js ├── bootstrap.js ├── jquery-1.10.2.js └── mod.js
widget 目錄
用來存放各類組件代碼。組件分成3類。
-
模板類:包含 tpl, 可以選擇性的添加 js 和 css 文件,同名的 js 和 css 會被自動(dòng)加載。
模板類文件,可以在模板中通過 widget 標(biāo)簽引用。如
{% widget "example:widget/pagelets/jumbotron/jumbotron.tpl" %} -
js 類: 主要包含 js 文件,放在此目錄下的文件一般都會自動(dòng)被 amd define 包裹,可選擇性的添加同名 css 文件,會自動(dòng)被引用。
此類組件,可以在 tpl 或者 js 中通過 require 標(biāo)簽引用。
-
純 css 類:只是包含 css 文件。比如 compass. 同樣也是可以通過 require 標(biāo)簽引用。
test 目錄。
用來存放測試數(shù)據(jù)和測試腳本。
測試數(shù)據(jù)。
在你本地預(yù)覽 page 目錄下的 tpl 的時(shí)候,會自動(dòng)在此目錄下找同名的 json 文件,并將數(shù)據(jù)與之關(guān)聯(lián)。
如 http://127.0.0.1:8080/example/page/index 預(yù)覽的是 example 模塊下,page/index.tpl 文件。如果 test/page/index.json 文件存在,則此 json 的里面的所有數(shù)據(jù)都可以在 tpl 里面使用到。
同時(shí),除了管理同名的 json 文件外,還會關(guān)聯(lián) test 目錄下同名的 js 文件,在 js 中可以動(dòng)態(tài)的添加數(shù)據(jù)。
/test/page/index.js
module.exports = function(req, res, setData) {
var origin = res.locals || {};
setData({
title: 'Overided ' + origin.title,
});};
另外:此目錄下還可存放其他文件,搭配 server.conf 配置,目錄各類線上頁面。
比如 test/data.json 文件,想通過 http://127.0.0.1:8080/testjson 頁面可以訪問到。只需要在 server.conf 里面配置如下內(nèi)容。
rewrite \/testjson$ /test/example/data.json
測試腳本
在 test 目錄下的 js,也可以像 jsp, php 一樣,寫些動(dòng)態(tài)的頁面。如:
/test/ajaxResponse.js
module.exports = function(req, res, next) {
res.write('Hello world');
res.setHeader('xxxx', 'xxx');
res.end('The time is ' + Date.now());};
配合 server.conf 可以用來模擬線上的 ajax 響應(yīng)頁面。
rewrite \/ajax$ /test/example/ajax.js
這樣當(dāng)你請求 http://127.0.0.1:8080/ajax 頁面的時(shí)候,就會自動(dòng)執(zhí)行這個(gè)腳本 js.
fis-conf.js
編譯配置文件,詳情請查看配置 API。
server.conf
用來配置頁面轉(zhuǎn)發(fā),支持 rewrite 和 redirect 兩條指令,此轉(zhuǎn)發(fā)功能只有在本地預(yù)覽中才有效。
語法非常簡單。
指令名稱 正則 目標(biāo)地址
栗子。
# 首頁 rewrite \/$ /example/page/index # json 文件 rewrite \/json /example/data.json # 自定義頁面。 rewrite \/ajax /example/ajax.js
非 rewrite, redirect 打頭的行,都被認(rèn)為是注釋。
BigPipe
采用 bigpipe 方案,允許你在渲染頁面的時(shí)候,提前將框架輸出,后續(xù)再把耗時(shí)的 pagelet 通過 chunk 方式輸出到頁面,以加速網(wǎng)頁渲染。
目前此機(jī)制已集成在 yogurt 中,通過給 widget 設(shè)置不同的模式便能自動(dòng)啟動(dòng)。
-
sync默認(rèn)就是此模式,直接輸出。 -
quicking此類 widget 在輸出時(shí),只會輸出個(gè)殼子,內(nèi)容由用戶自行決定通過 js,另起請求完成填充,包括靜態(tài)資源加載。 -
async此類 widget 在輸出時(shí),也只會輸出個(gè)殼子,但是內(nèi)容在 body 輸出完后,chunk 輸出 js 自動(dòng)填充。widget 將忽略順序,誰先準(zhǔn)備好,誰先輸出。 -
pipeline與async基本相同,只是它會嚴(yán)格按順序輸出。
后端的 controller 中可以通過 res.bigpipe.bind('pageletId', function() {}) 給頁面中 pagelet 延時(shí)綁定數(shù)據(jù)。
在前端模擬環(huán)境里面,則可以在通過在模擬數(shù)據(jù)的 js 文件中,通過設(shè)置 onPagelet 事件,延時(shí)給 pagelet 綁定數(shù)據(jù)。
test/page/index.js
module.exports = function(req, res, setData) {
setData({
onPagelet: function(id, cb) {
// id 為 pagelet 的 id
// 模擬異步獲取數(shù)據(jù)。
setTimeout(function() {
cb(null, {
title: id,
content: 'Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.'
});
// 隨機(jī)延時(shí)時(shí)間
}, 2000 * Math.random());
}
});}
要讓 bigpipe 正常運(yùn)行,需要前端引入 bigpipe.js, 另外 pagelet 為 quickling 模式,是不會自動(dòng)加載的,需要用戶主動(dòng)去調(diào)用 BigPipe.load 方法,才會加載并渲染。
更多信息請查看 yog-bigpipe;
后端結(jié)合
yogurt 負(fù)責(zé)前端部分的工作,將會產(chǎn)出以下文件。后端只需提供 controller 和 model, controller 中把 model 與 tpl 關(guān)聯(lián),然后選擇渲染模板文件。 關(guān)于后端框架部分,請查看 yog。
├── config │ └── example-map.json ├── public │ └── example │ ... 更多靜態(tài)資源文件 └── views └── example ... 更多模板文件
