ejs模板引擎原理

JuoJuo發表於2018-11-14
核心
  • 把html中的<%%>中的<%%>中的js保留執行,<%=%>替換成${xxx}拼接到模板字串上,test一執行返回的字串就是我們要的html
function test(obj) {
  let templ = ''
  with (obj) {
    templ += `<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>`;
    arr.forEach(item => {
      templ += `<li>${item.age}</li>`;
    })
    templ += `</body></html>`
  }
  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 += `<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>
//<% arr.forEach(item => { %>(替換前後一目瞭然的對應註釋)
  `; arr.forEach(item => { templ += `
//<li><%=item%></li>(替換前後一目瞭然的對應註釋)
  <li>${item.age}</li>
// <% }) %>(替換前後一目瞭然的對應註釋)
   `; }) templ += `
</body></html>
`}
return templ
複製程式碼

相關文章