一个简单的 JS 模板引擎

快过年了,需求不饱和,有时间写写博客。

What’s this?

这是一个清爽的 JavaScript 语法模板引擎,使用自带的 JavaScript 解释器,无中间语法,压缩后仅 0.45 kb。

思路:

  • 拆分语句与表达式(一次处理,提高性能)
  • 拼装 compiler 函数
  • 转义 html 中的单引号与转义符,保留函数与 html 格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Tpl(tpl) {
// 关于传递 RegExp https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/split
var snippet = tpl.split(/(?=<%)|(%>)/);
var mCode = [
'var _tplSnippet = [];',
'with(_tplData) {'
];
for (var i = 0; i < snippet.length; ++i) {
if (typeof snippet[i] !== 'undefined' && snippet[i] !== '%>') {
if (snippet[i].substring(0, 2) === '<%') {
// 如果是表达式
if (snippet[i].charAt(2) === '=') {
mCode.push(snippet[i].replace(/<%=((\s|.)+)/g, '_tplSnippet.push($1);'));
} else {
// 如果是语句
mCode.push(snippet[i].replace(/<%((\s|.)+)/g, '$1'));
}
} else {
// 如果是 html
mCode.push('_tplSnippet.push(\'' + snippet[i].replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/\n/g, '\\n') + '\');');
}
}
}
mCode.push('}', 'return _tplSnippet.join(\'\');');
return new Function('_tplData', mCode.join(''));
}

ShowCase

你可以在这里编辑模板与数据



性能

我做了一些测试,结果证明,即便是模板中包含大量复杂的业务逻辑,构建渲染函数过程的性能消耗也是微乎其微的,查看 TimeLine 时间大概在 1 毫秒左右。
因此可以见得,团队使用离线编译原生 JavaScript 语法的模板,主要是为了自动化、模块化以及安全考虑,而不是性能。