underscore模板编译

发布时间 2023-12-23 10:02:49作者: re大法好

什么是模板编译?

以前要渲染动态数据的话,都是服务器端渲染好了然后返回给客户端。类似于这样的模板(存在服务器上面,用户不可见的)

<div>姓名 <%= name %></div>
<div>是否是会员 <%= isVip %></div>

 

后服务器可以从数据库查询出姓名已经是否为vip,然后替换上面的模板后,转化成如下的结果返回给前端。

<div>姓名 李四</div>
<div>是否是会员 是</div>

 

具体的模板编译代码可以参考nodejs端的ejs或者python django端。

不过现在前端框架vue也流行这样的做法,将模板以及数据发送到前端,让用户的浏览器完成数据渲染。这样可以大大降低服务器渲染的压力。

 

如何在前端实现这样的模板编译?

目标实现

const template = `
<div>姓名 <%= name %></div>
<div>是否是会员 <%= isVip %></div>
`;

render(template)({name: '李四', 'isVip': '是'})  /* ' <div>姓名 李四</div> <div>是否是会员 是</div> ' */


const template = `
<ul>
    <% for (var i = 0, l = list.length; i < l; i ++) { %>
        <li>用户: <%=list[i].user%>/ 网站:<%=list[i].site%></li>
     <% } %>
 </ul>
`;

render(template)({list: [{user: 'aaa', site: 'www.baidu.com'}, {user: 'bbb', site: 'www.baidu2.com'}]})) 

 /* '<ul><li>用户:aaa/ 网站:www.baidu.com</li><li>用户:bbb/ 网站:www.baidu2.com</li></ul>' */

 

编译语言方式实现

词法阶段(lex, scan)

 将传进来的字符串转为一个个的token, 比如 ‘<div>姓名’ 是文本部分, <%= 是模板开始标记,  %>是模板结束标记,<% 是 js语法开始标记。

解析阶段(parser)

转为对应的js(emit)