说说如何用js实现一个模板引擎

本文同步更新在: https://github.com/whxaxes/blog/issues/4 ,在 github 看文章显示效果会更好一些。html

前言

不知不觉就很长时间没造过什么轮子了,之前一直想本身实现一个模板引擎,只是没付诸于行动,最近终于在业余时间里抽了点时间写了一下。由于咱们的项目大部分用的是 swig 或者 nunjucks ,因而就想实现一个相似的模板引擎。前端

至于为何要作这么一个东西?基本上每个作前端的人都会有本身的一个框架梦,而一个成熟的前端框架,模板编译能力就是其中很重要的一环,虽然目前市面上的大部分框架 vue、angular 这些都是属于 dom base 的,而 swig nunjucks ejs这些都是属于 string base 的,可是其实实现起来都是差很少的。不外乎都是 Template =parse=> Ast =render=>Stringvue

再者,作一个模板引擎,我的感受仍是对自身的编码能力的提高仍是颇有帮助的,在性能优化、正则、字符解析上尤其明显。在往后的业务需求中,若是有一些须要解析字符串相关的需求,也会更驾轻就熟。git

功能分析

一个模板引擎,在我看来,就是由两块核心功能组成,一个是用来将模板语言解析为 ast(抽象语法树)。还有一个就是将 ast 再编译成 html。github

先说明一下 ast 是什么,已知的能够忽略。编程

抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每一个节点都表示源代码中的一种结构。之因此说语法是“抽象”的,是由于这里的语法并不会表示出真实语法中出现的每一个细节。好比,嵌套括号被隐含在树的结构中,并无以节点的形式呈现;而相似于if-condition-then这样的条件跳转语句,可使用带有两个分支的节点来表示。性能优化

在实现具体逻辑以前,先决定要实现哪几种 tag 的功能,在我看来,forif elsesetraw还有就是基本的变量输出,有了这几种,模板引擎基本上也就够用了。除了 tag,还有就是 filter 功能也是必须的。前端框架

构建 AST

咱们须要把模板语言解析成一个又一个的语法节点,好比下面这段模板语言:框架

<div>
    {% if test > 1 %}
        {{ test }}
    {% endif %}
</div>

很明显,div 将会被解析为一个文本节点,而后接着是一个块级节点 if ,而后 if 节点下又有一个变量子节点,再以后有是一个 dom

相关文章
相关标签/搜索