ejs模板引擎原理

原文链接: https://juejin.im/post/5beb9349e51d4519cc247970
核心
  • 把html中的<%%>中的<%%>中的js保留执行,<%=%>替换成${xxx}拼接到模板字符串上,test一执行返回的字符串就是我们要的html
function test(obj) {
  let templ = ''
  with (obj) {
    templ += `Document`;
    arr.forEach(item => {
      templ += `
  • ${item.age}
  • `
    ; }) templ += `` } return templ } 复制代码
    • 核心代码:
    const fs = require('fs');
    const path = require('path');
    
    let str = fs.readFileSync(path.resolve(__dirname, 'index2.html'), 'utf8')
    
    function render(str) {
      let head = `let templ=''
      `;
      head += `with (obj){
        `;
    
      let content = `templ+=\``;
    
      //<%=%>替换成${xxx}
      str = str.replace(/<%=([\s\S]*?)%>/g, function () {
        return '${' + arguments[1] + '}';
      })
      //匹配<%%>,替换<%成反引号,替换%>成templ+=`,构成模板字符串
      content += str.replace(/<%([\s\S]*?)%>/g, function () {
        return `\`;
          ${arguments[1]}
          templ+=\``;
      })
    
      let tail = `\`}
      return templ`;
      return head + content + tail;
    }
    
    let res = render(str)
    console.log(res);
    
    //用字符串创建一个函数
    let fn = new Function('obj', res);
    let result = fn({
      name: 'lrj',
      arr: [{ age: 123 }, { age: 456 }]
    })
    console.log(result);
    
    复制代码

    -形象点但是难看点:

     let templ = ''
    with (obj) {
    templ += `Document
    //<% arr.forEach(item => { %>(替换前后一目了然的对应注释)
      `; arr.forEach(item => { templ += `
    //
  • <%=item%>
  • (替换前后一目了然的对应注释)
  • ${item.age}
  • // <% }) %>(替换前后一目了然的对应注释) `
    ; }) templ += ` `} return templ 复制代码

    你可能感兴趣的:(ejs模板引擎原理)