模板引擎

如何实现一个模板引擎?

常见模板引擎 ejs jade handlerbar underscore nunjunks

1
2
3
4
5
6
7
8
9
10
11
12
// 模板 template.html
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>模板</title>
</head>
<body>
<%=name%>
<%=age%>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// yarn add ejs
let ejs = require('ejs');
let fs = require('fs');
// fs.readFile异步 fs.readFileSync同步
let template = fs.readFileSync(__dirname+'/template.html', 'utf8');
let r = ejs.render(template, {name: 'jiafei', age: 18}); // 给模板提供一个name 返回的是渲染后的字符串
console.log(r);
/*****
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>模板</title>
</head>
<body>
jiafei
18
</body>
</html>
*/

自己实现一个模板引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 模板 template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
{%if(false){%}
hello
{%}else{%}
world
{%}%}
{%arr.forEach(item=>{%}
<li>{{item}}</li>
{%})%}
</body>
</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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
let fs = require("fs");
let template = fs.readFileSync(__dirname+"/template.html", "utf8");

function render(templateStr, obj) {
// {{name}}
let head = 'let str = "";\r\n';
head += "with(xxx){\r\n";
let content = "str += `"; // 取值
templateStr = templateStr.replace(/\{\{(.+?)\}\}/g, function() {
return "${" + arguments[1] + "}";
});
// 解析语法
content += templateStr.replace(/\{\%(.+?)\%\}/g, function() {
return "`\r\n" + arguments[1] + "\r\nstr+=`";
});
let tail = "`\r\n}\r\n return str;";
console.log("Str:", head + content + tail);
// 产生函数
let fn = new Function("xxx", head + content + tail);
return fn(obj);
// return templateStr.replace(/\{\{(.+?)\}\}/g,function(){
// return obj[arguments[1]]
// });
}
// 模板引擎的实现原理是: 1) with语法 2) new Function
let r = render(template, { arr: [1, 2, 3] });
console.log(r);

/********

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>

world


<li>1</li>

<li>2</li>

<li>3</li>

</body>
</html>
***/

Tips 模板引擎实现原理 (最简单的正则替换)

  • 1) with语法
  • 2) new Function 将字符串转化成函数
  • 3) 字符串拼接