一张图说明Ejs模板引擎的原理
上面一张图,已经大概把一个简单模板引擎(这里以EJS为例)的原理解释得七七八八了。本文将描述一个简单的模板引擎是怎么运作的?包含实现的关键步骤、以及其背后的思想。
基本上模板引擎的套路也就这样了,但这些思想是通用的,比如你在看vue的模板编译器源码、也可以套用这些思想和方法.
基本API设计
我们将实现一个简化版的EJS, 这个模板引擎支持这些标签:
<% script %> - 脚本执行. 一般用于控制语句,不会输出值 例如
<%if(user) {%>
some thing
<% } %>复制代码
<%= expression %> - 输出表达式的值,但是会转义HTML:
{%=title%}复制代码
<%- expression %> - 和 <%= expr %> 一样,只不过不会对HTML进行转义
<%% 和 %%> - 表示标签转义, 比如 <%% 会输出为 <%
<%# 注释 %> - 不会有内容输出
下面是一个完整的模板示例,下文会基于这个模板进行讲解:
<%= title %><%% 转义 %%><%# 这里是注释 %><%- before %><%if(show) {%>
root
<% } %>复制代码
基本API设计
我们将模板解析和渲染相关的逻辑放到一个Template类中,它的基本接口如下:
exportdefaultclassTemplate {publictemplate:string;privatetokens:string[] = [];privatesource:string="";privatestate?: State;privatefn?: Function;publicconstructor(template:string){this.template=template; }/**
* 模板编译
*/publiccompile(){this.parseTemplateText();this.transformTokens();this.wrapit(); }/**
* 渲染方法,由用户指定一个对象来渲染字符串
*/publicrender(local: object){ }/**
* token解析
* 将<% if (codintion) { %>
* 解析为token数组,例如['<%', ' if (condition) { ', '%>']
*/privateparseTemplateText(){}/**
* 将Token转换为Javascript语句
*/privatetransformTokens(){}/**
* 将上一个步骤转换出来的Javascript语句,封装