静态模板文件的内容,如 Handlebars模板等,多为字符串,若是直接部署上线,则须要在线上实时编译,引入的模板引擎也须要包含编译的部分。javascript
若是部署时以前先进行模板预编译,则:
1. 模板文件内容为一个预编译后生成的模板函数。
2. 线上的性能更高,由于再也不须要实时编译模板。
3. 引入的模板引擎更精简,能够将编译的部分功能去掉。html
使用 Handlebars 进行预编译,有几种方式。java
nodejs
具体安装方式可去官网查找,如今 Mac 和 Linux 版也有编译过的 Binaries
文件,没必要下载源码编译安装,设置一下 PATH
(增长一条,指向 $node_root/bin/
),NODE_PATH
(指向 $node_root/lib/node_modules/
) 变量便可,很是方便。node
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