1. 程式人生 > >【學習】tmodJS——前端模板預編譯技術

【學習】tmodJS——前端模板預編譯技術

什麼是前端模板預編譯

前端模板預編譯通過預編譯技術讓前端模板突破瀏覽器限制,實現後端模板一樣的同步“檔案”載入能力。它採用目錄來組織維護前端模板,從而讓前端模板實現工程化管理,最終保證前端模板在複雜單頁 web 應用下的可維護性。同時預編譯輸出的程式碼經過多層優化,能夠在最大程度節省客戶端資源消耗。

按檔案與目錄組織模板

template('tpl/home/main', data)

模板支援引入子模板

{{include '../public/header'}}

TmodJS 一經啟動,就無需人工干預,每次模板建立與更新都會自動編譯,引入一個 js 即可使用template(path)介面呼叫本地模板檔案,直到正式上線都無需對程式碼進行任何修改,整個過程簡單自然。

強大之處

  1. 編譯模板為不依賴引擎的 js 檔案
  2. 前端模板按檔案與目錄組織
  3. 模板之間支援引入外部模板
  4. 使用同步模板載入介面
  5. 可選多種規範的模組輸出:AMD、CMD、CommonJS
  6. 支援作為 GruntJS 的外掛構建專案
  7. 模板目錄可被前後端共享
  8. 支援檢測修改即時編譯
  9. 支援模板執行時除錯
  10. 配置檔案支援多人共享

使用tmodJS

全域性安裝

npm install -g tmodjs

編寫模板

TmodJS 的前端模板不再耦合在業務頁面中,而是和後端模板一樣有專門的目錄管理。目錄名稱只支援英文、數字、下劃線的組合,一個模板對應一個.html檔案。

模板語法

和artTemplate一脈相承,建議協同使用。

表示式

{{ 與 }} 符號包裹起來的語句則為模板的邏輯表示式。

輸出表達式

對內容編碼輸出:

{{content}}

不編碼輸出(編碼可以防止資料中含有 HTML 字串,避免引起 XSS 攻擊)

{{#content}}

條件表示式

{{if admin}}
    <p>admin</p>
{{else if code > 0}}
    <p>master</p>
{{else}}
    <p>error!</p>
{{/if}}

遍歷表示式

無論陣列或者物件都可以用 each 進行遍歷。

{{each list as value index}}
    <li>{{index}} - {{value.user}}</li>
{{/each}}

亦可以被簡寫:

{{each list}}
    <li>{{$index}} - {{$value.user}}</li>
{{/each}}

模板包含表示式

用於嵌入子模板:

{{include 'template_name'}}

子模板預設共享當前資料,亦可以指定資料:

{{include 'template_name' news_list}}

include 路徑規範約定

  1. 路徑不能帶字尾名
  2. 路徑不能夠進行字串運算
  3. 路徑不能使用變數代替
  4. 必須使用以.開頭的相對路徑

輔助方法

{{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}}

支援傳入引數與巢狀使用:

{{time | say:'cd' | ubb | link}}

為了模板可維護,模板本身是不能隨意訪問外部資料的,它所有的語句都將執行在一個沙箱中。如果需要訪問外部物件可以註冊輔助方法,這樣所有的模板都能訪問它們。

新建一個輔助方法檔案配置
在模板目錄新建一個 config/template-helper.js 檔案,然後編輯 package.json 設定”helpers”: “./config/template-helper.js”。

編寫輔助方法
在 config/template-helper.js 中宣告輔助方法。

以日期格式化為例:

template.helper('dateFormat', function (date, format) {

    date = new Date(date);

    var map = {
        "M": date.getMonth() + 1, //月份 
        "d": date.getDate(), //日 
        "h": date.getHours(), //小時 
        "m": date.getMinutes(), //分 
        "s": date.getSeconds(), //秒 
        "q": Math.floor((date.getMonth() + 3) / 3), //季度 
        "S": date.getMilliseconds() //毫秒 
    };
    format = format.replace(/([yMdhmsqS])+/g, function(all, t){
        var v = map[t];
        if(v !== undefined){
            if(all.length > 1){
                v = '0' + v;
                v = v.substr(v.length-2);
            }
            return v;
        }
        else if(t === 'y'){
            return (date.getFullYear() + '').substr(4 - all.length);
        }
        return all;
    });
    return format;
});

呼叫:

{{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}}

編譯模板

只需要執行tmod這個命令即可,預設配置引數可以滿足絕大多數專案。

tmod [模板目錄] [配置引數]

注意:模板目錄必須是模板的根目錄,若無引數則為預設使用當前工作目錄,tmodjs 會監控模板目錄修改,每次模板修改都會增量編譯。

配置引數

  • --debug 輸出除錯版本
  • --charset value 定義模板編碼,預設utf-8
  • --output value 定義輸出目錄,預設./build
  • --type value 定義輸出模組格式,預設default,可選cmdamdcommonjs
  • --no-watch 關閉模板目錄監控
  • --version 顯示版本號
  • --help 顯示幫助資訊

注意:配置引數將會儲存在模板目錄配置檔案中,下次執行無需輸入配置引數(–no-watch 與 –debug 除外)。

舉個例子

tmod ./tpl --output ./build

使用模板

根據編譯的 type 的配置不同,會有兩種不同使用方式:

使用預設的格式

TmodJS 預設將整個目錄的模板壓縮打包到一個名為 template.js 的指令碼中,可直接在頁面中使用它:

<script src="tpl/build/template.js"></script>
<script>
    var html = template('news/list', _list);
    document.getElementById('list').innerHTML = html;
</script>

指定格式(amd / cmd / commonjs)

此時每個模板就是一個單獨的模組,無需引用 template.js:

var render = require('./tpl/build/news/list');
var html = render(_list);

注意:模板路徑不能包含模板字尾名

演示

TmodJS 原始碼包中test/tpl是一個演示專案的前端模板目錄,基於預設配置。切換到原始碼目錄後,編譯:

tmod test/tpl

編譯完畢後你可以在瀏覽器中開啟 test/index.html 檢視如何使用編譯後的模板。

配置

TmodJS 的專案配置檔案儲存在模板目錄的 package.json 檔案中:

{
    "name": "template",
    "version": "1.0.0",
    "dependencies": {
        "tmodjs": "1.0.0"
    },
    "tmodjs-config": {
        "output": "./build",
        "charset": "utf-8",
        "syntax": "simple",
        "helpers": null,
        "escape": true,
        "compress": true,
        "type": "default",
        "runtime": "template.js",
        "combo": true,
        "minify": true,
        "cache": false
    }
}

這裡寫圖片描述

gulp配置

讓 TmodJS 作為 Gulp 的一個外掛使用:

npm install gulp-tmod --save-dev

常見Q&A

問:TmodJS 需要部署到伺服器中嗎?

不需要,這是本地工具,基於 NodeJS 編寫是為了實現跨平臺。

問:如何將每個模板都編譯成單獨的 amd/cmd 模組輸出?

指定 type 引數即可,如–type cmd則可以讓每個模板都支援 RequireJS/SeaJS 呼叫。

問:如何將模板編譯成 NodeJS 的模組?

指定 type 引數即可,如–type commonjs。

問:線上執行的模板報錯了如何除錯?

開啟 debug 模式編譯,如–debug,這樣會輸出除錯版本,可以讓你快速找到模板執行錯誤的語句以及資料。

問:如何不壓縮輸出 js?

編輯配置檔案,設定”minify”: false。

問:如何修改預設的輸出目錄?

指定 output 引數即可,如–output ../../build

如何讓模板訪問全域性變數?

具體參考上面的 輔助方法

問:可以使用使用類似 tmpl 那種的 js 原生語法作為模板語法嗎?

可以。編輯配置檔案,設定”syntax”: “native”即可,目前 TmodJS 預設使用的是 simple 語法。

問:如何相容舊版本 atc 的專案?

編輯配置檔案,分別設定”type”: “cmd”、”syntax”: “native”、”output”: “./”

問:如何遷移原來寫在頁面中的 artTemplate 模板,改為 TmodJS 這種按按檔案存放的方式?

問:我需要手動合併模板,如何讓 tmodjs 不合並輸出?

編輯配置檔案,設定combo:false。