Handlebars模板部署時發佈爲預編譯過的模板函數

靜態模板文件的內容,如 Handlebars模板等,多爲字符串,若是直接部署上線,則須要在線上實時編譯,引入的模板引擎也須要包含編譯的部分。javascript

若是部署時以前先進行模板預編譯,則:
1. 模板文件內容爲一個預編譯後生成的模板函數。
2. 線上的性能更高,由於再也不須要實時編譯模板。
3. 引入的模板引擎更精簡,能夠將編譯的部分功能去掉。html

使用 Handlebars 進行預編譯,有幾種方式。java

首先須要安裝 nodejs

具體安裝方式可去官網查找,如今 Mac 和 Linux 版也有編譯過的 Binaries 文件,沒必要下載源碼編譯安裝,設置一下 PATH (增長一條,指向 $node_root/bin/),NODE_PATH (指向 $node_root/lib/node_modules/) 變量便可,很是方便。node

安裝 Handlebars

npm install -g handlebars 根據狀況決定是否安裝到全局。npm

編譯模板文件

按照 Handlebars 官網的說法,只需:handlebars <input> -f <output> 便可。函數

可是這種方式侷限性很是大。
1. 必須在命令行直接使用 handlebars 命令,不太容易配合 build 工具
2. 生成的編譯後的模板內容(函數),被直接賦值給了 Handlebars.templates 字典,且 key 被設置爲 文件名 ,而非 路徑名模塊名,容易 命名衝突!這樣的話,須要後期本身處理。
這樣一來,頁面的引用方式會有較大變化,即:工具

var a, b, tpl = require('./path/to/tpl.tpl');
var tpl = Handlebars.compile(tpl);

變爲:性能

require('./path/to/tpl.tpl');
var tpl = Handlebars.templates['tpl.tpl'];

變化太大,很難用自動化的工具還自動改變引用(除非用很強的書寫約定)。ui

更好的方式:
寫一段 compile.js 腳本:this

var fs = require('fs');
var h = require('handlebars');

var compiledFn = h.precompile(fs.readFileSync('path/to/tpl.tpl'));
// 根據狀況 能夠將內容先轉換爲 seajs 模塊,再 writeFile
var content = 'define("xx/id",[],function(){return ' + compiledFn + '});';
fs.writeFileSync('path/to/dest/tpl.tpl.js', content);

而後再引用的地方只需將 Handlebars.compile 改成 Handlebars.template 便可(根據狀況,require 的路徑作相應調整):

var a,b, tpl = require('./path/to/tpl.tpl.js');
var tpl = Handlebars.template(tpl);

下面舉一個實例來演示:

開發時的結構可能以下(假設與 seajs 配合):

__index.html
  |__script
  |  |__index.js
  |__tpl
  |  |__index.tpl
  |__style

index.html 內容以下:

...<scritp>
seajs.use('./index');
</script>...

index.js 內容以下:

define(function(require){
    // 若是沒有引入 seajs-text.js 插件,
    // 則:require('../tpl/index.tpl.js');
    var tplStr = require('../tpl/index.tpl');
    var tplFn = Handlebars.compile(tplStr);

    var context = {
        Title: 'Hi, Handlebars!'
    };
    var html = tplFn(context);
});

index.tpl 內容以下:

<div>
    <h1>{{Title}}</h1>
</div>

部署時,運行上面提到的 compile.js,以後:
index.html 不變,index.js 內容:

...
// 其實這裏已是編譯後的函數了,而非 String
var tplStr = require('../tpl/index.tpl.js');
var tplFn = Handlebars.template(tplStr);
...

index.tpl.js 內容以下:

define("id",[], function(require, exports, module){
    // 或 return function (Handlebars, ...
    module.exports = function (Handlebars,depth0,helpers,partials,data) {
        this.compilerInfo = [4,'>= 1.0.0'];
        helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
        var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;


        buffer += "<div>\r\n  <p>";
        if (stack1 = helpers.Title) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
        else { stack1 = (depth0 && depth0.Title); stack1 = typeof stack1 === functionType ? stack1.call(depth0, {hash:{},data:data}) : stack1; }
        buffer += escapeExpression(stack1)
          + "</p>\r\n</div>";
        return buffer;
  }
});

轉載請註明來自[超2真人]
本文連接:http://www.peichao01.com/static_content/doc/html/Handlebars_precompile.html

相關文章
相關標籤/搜索