js模板引擎--artTemplate
以前研究過一段時間的handlebars,但因為其渲染性能略遜於騰訊的artTemplate(在artTemplate的GitHub官網上有推薦的性能測試地址),貌似最近耳邊聽到得最多的模板引擎也就是artTemplate了,所以就花個時間來研究下吧...
artTemplate是新一代的javascript模板引擎,若采用擁有V8引擎的chrome瀏覽器進行測試,其渲染性能甚至能達到知名模板引擎Mustache的20倍以上以及模板引擎tmpl的40倍以上,測試截圖如下:

下面進入正題:
特性
- 性能卓越,執行速度通常是 Mustache 與 tmpl 的 20 多倍
- 支持運行時調試,可精確定位異常模板所在語句
- 對 NodeJS Express 友好支持
- 安全,默認對輸出進行轉義、在沙箱中運行編譯后的代碼(Node版本可以安全執行用戶上傳的模板)
- 支持
include語句 - 可在瀏覽器端實現按路徑加載模板
- 支持預編譯,可將模板轉換成為非常精簡的 js 文件
- 模板語句簡潔,無需前綴引用數據,有簡潔版本與原生語法版本可選
- 支持所有流行的瀏覽器
快速上手
編寫模板(采用script標簽並帶有屬性id和type="text/html")
<script id="test" type="text/html">
{{if isAdmin}}
<h1>{{author}}</h1>
<ul>
{{each list as value i}}
<li>{{i+1}}:{{value}}</li>
{{/each}}
</ul>
{{/if}}
</script>
渲染模板
1 var data = {
2 author: '宮崎駿',
3 isAdmin: true,
4 list: ['千與千尋', '哈爾的移動城堡', '幽靈公主', '風之谷', '龍貓']
5 };
6 var html = template('test', data);
7 document.getElementById('content').innerHTML = html;
模板語法
有兩個版本的模板語法可以選擇。
1.簡潔語法(采用"{{ }}",推薦使用)
<script id="test" type="text/html">
{{if admin}}
{{include 'admin_content'}}
{{each list}}
<div>{{$index}}.{{$value.user}}</div>
{{/each}}
{{/if}}
</script>
2.原生語法(采用"<%= %>")
<script id="test" type="text/html">
<%if {%>
<%include('admin_content')%>
<%for (var i=0;i<list.length;i++) {%>
<div><%=i%>.<%=list[i].user%></div>
<%}%>
<%}%>
</script>
下載地址
- template.js (簡潔語法版, 2.7kb)
- template-native.js (原生語法版, 2.3kb)
方法
1. template(id, data)
根據 id 渲染模板。內部會根據document.getElementById(id)查找模板,如果沒有 data 參數,那么將返回一渲染函數。
1 //修改代碼前
2 var data = {
3 author: '宮崎駿',
4 isAdmin: true,
5 list: ['千與千尋', '哈爾的移動城堡', '幽靈公主', '風之谷', '龍貓']
6 };
7 var html = template('test', data);
8 document.getElementById('content').innerHTML = html;
9
10 //修改代碼后
11 var data = {
12 author: '宮崎駿',
13 isAdmin: true,
14 list: ['千與千尋', '哈爾的移動城堡', '幽靈公主', '風之谷', '龍貓']
15 };
16 var html = template('test');
17 console.log(html);
控制台輸出結果如下圖:

2. template.compile(source, options)
將返回一個渲染函數。
1 <h1>用變量存放模板</h1>
2 <div id="content"></div>
3 <script>
4 var source = '<ul>' +
5 '{{each list as value i}}' +
6 '<li>{{i+1}}.{{value}}</li>' +
7 '{{/each}}' +
8 '</ul>';
9 var render = template.compile(source);
10 var html = render({
11 list: ['千與千尋', '哈爾的移動城堡', '幽靈公主', '風之谷', '龍貓']
12 });
13 document.getElementById('content').innerHTML = html;
14 </script>
3. template.render(source, options)
將返回一個渲染結果。
4. template.helper(name, callback)
將返回一個渲染結果。
1 <script id="test" type="text/html">
2 {{time | dateFormat: 'yyyy年 MM月 dd日 hh:mm:ss'}}
3 </script>
4 <script>
5 template.helper('dateFormat', function(date, format) {
6 var date = new Date(date);
7 var map = {
8 M: date.getMonth() + 1, //月份
9 d: date.getDate(), //日
10 h: date.getHours(), //小時
11 m: date.getMinutes(), //分
12 s: date.getSeconds(), //秒
13 q: Math.floor((date.getMonth() + 3) / 3), //季度
14 S: date.getMilliseconds() //毫秒
15 };
16 var format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
17 var v = map[t];
18 if (v !== undefined) {
19 if (all.length > 1) {
20 v = '0' + v;
21 v = v.substr(v.length - 2);
22 }
23 return v;
24 } else if (t === 'y') {
25 return (date.getFullYear() + '').substr(4 - all.length);
26 }
27 return all;
28 });
29 return format;
30 });
31 // ---------
32 var data = {
33 time: new Date().toString()
34 };
35 var html = template('test', data);
36 document.getElementById('content').innerHTML = html;
37 </script>
5. template.config(name, value)
更改引擎的默認配置。
| 字段 | 類型 | 默認值 | 說明 |
|---|---|---|---|
| openTag | String | '{{' |
邏輯語法開始標簽 |
| closeTag | String | "}}" |
邏輯語法結束標簽 |
| escape | Boolean | true |
是否編碼輸出 HTML 字符 |
| cache | Boolean | true |
是否開啟緩存(依賴 options 的 filename 字段) |
| compress | Boolean | false |
是否壓縮 HTML 多余空白字符 |
使用預編譯
可突破瀏覽器限制,讓前端模板擁有后端模板一樣的同步“文件”加載能力:
一、按文件與目錄組織模板
template('tpl/home/main', data)
二、模板支持引入子模板
{{include '../public/header'}}
基於預編譯
- 可將模板轉換成為非常精簡的 js 文件(不依賴引擎)
- 使用同步模板加載接口
- 支持多種 js 模塊輸出:AMD、CMD、CommonJS
- 支持作為 GruntJS 插件構建
- 前端模板可共享給 NodeJS 執行
- 自動壓縮打包模板
預編譯工具:TmodJS
NodeJS
安裝
npm install art-template
使用
var template = require('art-template'); var data = {list: ["aui", "test"]}; var html = template(__dirname + '/index/main', data);
配置
NodeJS 版本新增了如下默認配置:
| 字段 | 類型 | 默認值 | 說明 |
|---|---|---|---|
| base | String | '' |
指定模板目錄 |
| extname | String | '.html' |
指定模板后綴名 |
| encoding | String | 'utf-8' |
指定模板編碼 |
配置base指定模板目錄可以縮短模板的路徑,並且能夠避免include語句越級訪問任意路徑引發安全隱患,例如:
template.config('base', __dirname); var html = template('index/main', data)
NodeJS + Express
var template = require('art-template'); template.config('base', ''); template.config('extname', '.html'); app.engine('.html', template.__express); app.set('view engine', 'html'); //app.set('views', __dirname + '/views');
運行 demo:
node demo/node-template-express.js

