本文同步更新在: https://github.com/whxaxes/blog/issues/4 ,在 github 看文章顯示效果會更好一些。html
不知不覺就很長時間沒造過什麼輪子了,之前一直想本身實現一個模板引擎,只是沒付諸於行動,最近終於在業餘時間裏抽了點時間寫了一下。由於咱們的項目大部分用的是 swig 或者 nunjucks ,因而就想實現一個相似的模板引擎。前端
至於爲何要作這麼一個東西?基本上每個作前端的人都會有本身的一個框架夢,而一個成熟的前端框架,模板編譯能力就是其中很重要的一環,雖然目前市面上的大部分框架 vue、angular 這些都是屬於 dom base 的,而 swig nunjucks ejs這些都是屬於 string base 的,可是其實實現起來都是差很少的。不外乎都是 Template
=parse=> Ast
=render=>String
。vue
再者,作一個模板引擎,我的感受仍是對自身的編碼能力的提高仍是頗有幫助的,在性能優化、正則、字符解析上尤其明顯。在往後的業務需求中,若是有一些須要解析字符串相關的需求,也會更駕輕就熟。git
一個模板引擎,在我看來,就是由兩塊核心功能組成,一個是用來將模板語言解析爲 ast(抽象語法樹)。還有一個就是將 ast 再編譯成 html。github
先說明一下 ast 是什麼,已知的能夠忽略。編程
抽象語法樹(abstract syntax tree或者縮寫爲AST),或者語法樹(syntax tree),是源代碼的抽象語法結構的樹狀表現形式,這裏特指編程語言的源代碼。樹上的每一個節點都表示源代碼中的一種結構。之因此說語法是「抽象」的,是由於這裏的語法並不會表示出真實語法中出現的每一個細節。好比,嵌套括號被隱含在樹的結構中,並無以節點的形式呈現;而相似於if-condition-then這樣的條件跳轉語句,可使用帶有兩個分支的節點來表示。性能優化
在實現具體邏輯以前,先決定要實現哪幾種 tag 的功能,在我看來,for
,if else
,set
,raw
還有就是基本的變量輸出,有了這幾種,模板引擎基本上也就夠用了。除了 tag,還有就是 filter 功能也是必須的。前端框架
咱們須要把模板語言解析成一個又一個的語法節點,好比下面這段模板語言:框架
<div> {% if test > 1 %} {{ test }} {% endif %} </div>
很明顯,div 將會被解析爲一個文本節點,而後接着是一個塊級節點 if ,而後 if 節點下又有一個變量子節點,再以後有是一個 dom