前端开发系列116-进阶篇之模板引擎的实现方式
本文以ejs为例,简单介绍模板引擎的实现原理。
模板引擎(ejs)的使用示例
先提供一个模板文件。
<!-- 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>
<%=author%><%=age%><%=address%>
<%arr.forEach(item=>{%>
<li><%=item%></li>
<%})%>
</body>
</html>
这里给出ejs引擎的使用示例,在执行前需要先执行npm init -y
和npm i ejs
命令来安装模块。
const ejs = require("ejs");
const path = require("path");
ejs.renderFile(path.resolve(__dirname, "template.html"),
{author: "文顶顶", age:18, address:"远方", arr:["liuYi", "MiaoXia", "XiaoXia", "Jia"]},
(err, data) => {
console.log(err, data);
})
运行上面的代码来进行渲染,将得到下面的html页面。
null <!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>
文顶顶 18 远方
<li> lY </li>
<li> MiaoXia </li>
<li> XiaoXia </li>
<li> Jia </li>
</body>
</html>
实现原理
模板引擎的实现原理本质上就是利用
new Function
来执行字符串,利用with特性
来框定作用域传递数据,利用正则表达式
来实现特定字符的替换工作,再加上冗长的字符串拼接。
给出自己写的readFile文件代码。
const fs = require("fs");
const path = require("path");
let renderFile = (filePath, obj, cb) => {
/* 1、先读取文件的内容 */
fs.readFile(filePath, "utf-8", (err, html) => {
if (err) {
cb(err, html);
}
/* 2、拼接字符串 */
let head = "let str = '';\r\n with(obj){";
head += "str +=`";
/* 使用正则处理<%=author%>部分 替换为${author} */
let body = html.replace(/<\%=([^%]+)\%>/g, function() {
return "${" + arguments[1] + "}";
});
/* 继续使用正则处理<%arr.forEach(item=>%>部分 删除标签 */
body = body.replace(/<\%([^%]+)\%>/g, function() {
return "`;\r\n" + arguments[1] + "\r\nstr+=`";
});
let end = "`}";
html = head + body + end + "return str";
/* 3、执行字符串(new Function) */
let fn = new Function('obj', html);
/* 4、执行回调传递渲染后的结果 */
cb(null, fn(obj))
})
}
renderFile(path.resolve(__dirname, "template.html"),
{author: "文顶顶",age:18, address:"远方", arr: ["liuYi", "MiaoXia", "XiaoXia", "Jia"]},
(err, data) => {
console.log(err, data);
})