模板引擎

336 阅读1分钟

  • 模板引擎框架:ejs jade undescore handlebar nunjunks {{name}}
  • 所有的引擎核心就是数据替换

模拟es6的模板字符串

let name = 'jaasdsa';
let age = 18;
let str = "${name}今年${age}岁了";
let reg = /\${([\s\S]+?)}/g;
// let r = str.match(reg);
// console.log(r);

//  [\s\S]+? 尽可能少匹配
// () 分组 会将匹配到的结果 放到arguments
let rr = str.replace(reg, function(world, value) {
    console.log(world, value);
    return eval(value);
});
console.log(rr);

ejs模板引擎原理

  • 必备知识1:模板引擎原理 with语法
let obj = { name: 'jaasdsa' };
with(obj) {
    console.log(name);
}
  • 必备知识2:字符串变成执行函数
let fn = new Function(`console.log('jaasdsa')`);
fn();
  • 模拟实现ejs模板引擎原理
let fs = require('fs');
let templateStr = fs.readFileSync('./template.html', 'utf-8');
//console.log(templateStr);

// 模拟实现ejs模板引擎原理
function render(str, renderObj) {
    // 拼接的是一个纯字符串
    let head = 'let str="";\r\nwith(name){\r\nstr = `\r\n';
    str = str.replace(/<%=([\s\S]+?)%>/g, function() {
        return '${' + arguments[1] + '}'
    })
    let content = str.replace(/<%([\s\S]+?)%>/g, function() {
        return '`\r\n' + arguments[1] + '\r\nstr+=`'
    });
    let tail = '`\r\n}\r\n return str'
    let s = head + content + tail;
    // console.log(s);
    return new Function('name', s)(renderObj);
}
let renderStr = render(templateStr, {
    name: [1, 2, 3]
});
console.log(renderStr);
  • template.html
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>
</head>

<body>
    <%name.forEach(item=>{%>
        <li>
            <%=item%>
        </li>
        <%})%>
</body>

</html>
  • 预览生成字符串函数
function fn(name) {
    let str = "";
    with(name) {
        str = `
<!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>
  `
        name.forEach(item => {
            str += `
      <li>
          ${item}
      </li>
      `
        })
        str += `
</body>

</html>`
    }
    return str
}
  • 输出结果
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>
</head>

<body>
    
        <li>
            1
        </li>
        
        <li>
            2
        </li>
        
        <li>
            3
        </li>
        
</body>

</html>