new Function + with + 字符串拼接 实现html模版

286 阅读1分钟
test文件
function a(obj){
    let str = ''
    with(obj){
        str += `<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
        </head>
        <body>`
            arr.forEach(item => {
                str += `<li></li>`
            })
        str += `</body>
        </html>`
    }
    return str
    
}
console.log(a({arr:[1,2,3]}))

运行结果:

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

由上可知:1,with 确定了默认this的指向 2,a函数运行时实现了str的拼接

template.html 文件

这是html模版

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

    {% arr.forEach(item => { %}
        <li>{{item}}</li>
    {%})%}
    
</body>
</html>
template.js 文件

这是解析html文件 生成模板

const ejs = require('ejs') //第三方模块

const path = require('path')//path模块

const fs = require('fs')//文件模块

//解析函数
const renderFile = (filePath,obj,cb) => {
    //调取文件模块fs 读取html模板
    fs.readFile(filePath,'utf8',function(err,html){
        if(err){
            return cb(err,html)
        }
        //讲读取到的html 中的{{ name }} 等模版用正则匹配 并且替换到html中
        html = html.replace(/\{\{([^}]+)\}\}/g,function(){
            let key = arguments[1].trim()
            return '${' + key +'}'
        })
        //文件的头部和上面test文件的a函数对比一下  用字符串str将html拼接起来
        //里面包括了with语法
        let head = `let str = '';\r\n with(obj){\r\n`
        head += 'str +=`'
        // 将html字符串中的{% item %} 替换成 item
        html = html.replace(/\{\%([^%]+)\%\}/g,function(){
            return '`\r\n'+arguments[1] +'\r\n str += `\r\n'
        })
        let tail = '`}\r\n return str;'
        //用new Function 将字符串转换成一个函数
        let fn = new Function('obj',head + html + tail)
        //执行调用时的回调 并传入fn函数 fn就是用new Function 生成的函数
        cb(err,fn(obj))
        // console.log(html)
    })
}

renderFile(path.resolve(__dirname,'template.html'),{name:'eee',age:'234',arr:[1,3,4,5]},function(err,data){

    console.log(data,'rrrrrrr')
})