返回
不用正则表达式,用javascript从零写一个模板引擎(一)
前端
2023-10-19 02:00:19
前言
模板引擎的作用就是将模板渲染成html,html = render(template,data),常见的js模板引擎有Pug,Nunjucks,Mustache等。网上一些制作模板引擎的文章大部分是用正则表达式做一些hack工作,看完能收获的东西很少。本文将使用编译原理那套理论,实现模板解析和渲染,把市面上大部分模板引擎囊括其中。
整体设计
对于一个模板引擎,其主要组成部分有:
- 模板解析器 :将模板解析成AST(抽象语法树)
- AST优化器 :对AST进行优化
- 渲染器 :将AST渲染为html
一个模板引擎的整体流程如下图所示:
模板解析
模板解析器将模板解析成AST,AST可以表示模板的结构,方便后续的优化和渲染。
词法分析
词法分析器将模板字符串切分为一个个的token,token可以是变量、表达式、标签等。例如,下面的模板:
<h1>{{title}}</h1>
<p>{{content}}</p>
词法分析器会将它切分为以下token:
[
{
type: 'tag',
value: '<h1>'
},
{
type: 'variable',
value: 'title'
},
{
type: 'tag',
value: '</h1>'
},
{
type: 'tag',
value: '<p>'
},
{
type: 'variable',
value: 'content'
},
{
type: 'tag',
value: '</p>'
}
]
语法分析
语法分析器将token序列解析成AST,AST可以表示模板的结构。例如,上面的token序列可以解析成以下AST:
{
type: 'root',
children: [
{
type: 'tag',
value: '<h1>',
children: [
{
type: 'variable',
value: 'title'
}
]
},
{
type: 'tag',
value: '<p>',
children: [
{
type: 'variable',
value: 'content'
}
]
}
]
}
AST优化
AST优化器对AST进行优化,以提高渲染速度。例如,AST优化器可以将相邻的文本节点合并成一个文本节点,还可以将一些不必要的节点删除。
渲染
渲染器将AST渲染为html,渲染器可以是一个函数,也可以是一个类。例如,下面的渲染器可以将上面的AST渲染为html:
function render(ast) {
let html = '';
for (let i = 0; i < ast.children.length; i++) {
const child = ast.children[i];
if (child.type === 'tag') {
html += child.value;
if (child.children) {
html += render(child);
}
} else if (child.type === 'variable') {
html += data[child.value];
}
}
return html;
}
总结
本文介绍了如何从零编写一个模板引擎,包括模板解析、AST优化和渲染三个主要部分。希望本文能帮助你对模板引擎有更深入的了解,并能让你在实际项目中使用模板引擎。