EJS[0]-如何使用EJS
- 2019 年 12 月 5 日
- 筆記
EJS[0]-如何使用EJS
最近做的一個新項目,所以想着換一個新的模版引擎嘗試一下。(之前我們一直在使用
handlebars
) 本次源碼分析所使用的是TJ大神開發的1.x版本 當然現在該項目已經停止維護了,目前正在維護的是2.x版本
什麼是EJS
EJS
是一個JavaScript
模版庫,用來將EJS
模版結合著JSON
數據轉換為HTML
並且可以直接在模版中寫JavaScript
的語法
簡單的示例
let template = '<h1>Hello, <%= name %></h1>' let data = { name: 'Niko Bellic' } let renderStr = ejs.render(template, data) console.log(renderStr) // => <h1>Hello, Niko Bellic</h1>
EJS
模版主要還是HTML
標籤,僅僅添加了幾對特定的標籤(<% %>
, <%= %>
, <%- %>
, <% -%>
, <%# %>
)。
為什麼要用EJS
近年來,前端各種MV*框架層出不窮,React
,Angular
,Vue
,當然這應該也是未來幾年的趨勢了,但是這些大都是前端運行時進行渲染,動態的生成HTML
。 (React
是有着服務端渲染的解決方案,為了解決SEO的問題) 但是EJS
這類的模版引擎是不依賴於宿主語言環境的,只要是JavaScript
即可,也就是說可以用於server
端(node.js
)直接渲染,返回給前端渲染好的頁面。(這個在大部分後台頁面的開發中還是需要的) 當請求某個鏈接時,直接將渲染完成的頁面呈現給用戶,主要的作用有兩點:
- 避免了代碼都存在前端,被某些惡意用戶看到。
- 對搜索引擎SEO更友好。
當然,MV*
框架依然是近幾年的趨勢,也是建議多去使用和研究那些框架,但是模版引擎和前端的那幾個框架並不衝突,也是可以一起使用的。
如何使用EJS
EJS
提供了數個標籤來供我們使用,在標籤內可以直接寫JavaScript
代碼,如果使用服務端來渲染,你甚至可以直接引用一些npm
包,來做一些想做的事情。
<% code %>
EJS
會執行標籤內的代碼,一般用於邏輯處理或者循環創建使用。
<% if (user) { %> <h2><%= user.name %></h2> <% } %>
如上文在EJS
處理後的代碼應該是類似這個樣子的。(源代碼比這個內容更豐富一些。。。)
(function () { var buf = [] if (user) { buf.push('<h2>') buf.push(user.name) buf.push('</h2>') } return buf.join('') })
<%- code %>
EJS
會將標籤內的代碼執行,並獲取返回值,將返回值輸出到字符串中。
<span><%= 'Hello' %></span> <!-- convert --> <span>Hello</span>
<%= code %>
<%= code %>
與<%- code %>
類似,只不過會將返回值進行轉義後輸出。
<span><%= '<hello />' %></span> <!-- convert --> <span><hello /></span>
<%# comment %>
昂。。這個標籤裡邊的內容是作為注釋存在的。。估計很少有人會用-.- 在模版生成後,會移除裡邊的內容
在標籤後邊添加-
這個有很多種寫法都可以支持,比如:<% -%>
,<%= -%>
,<%- -%>
這樣會移除該標籤後邊的第一個換行符(如果有的話)
<h1> <%- 'Title' %> </h1> <!-- convert --> <h1> Title </h1> <!-- line --> <h1> <%- 'Title' -%> </h1> <!-- convert --> <h1> Title</h1>
模版提供的各種Config
cache
默認為false
,如果設置為true
則認為是開啟了緩存模式,對相同filename
參數的模版會使用之前已經渲染好的。 前置條件:必須同時設置filename
參數
filename
cache
模式下作為一個存儲的key
。
scope
可以通過該參數設置模版執行時的函數上下文。 即模版中this
的指向。
debug
默認為false
,如果設置為true
,則會在模版執行compile
時輸出拼接好的JavaScript
代碼。方便調試。
compileDebug
默認為開啟,設置為false
則為關閉,在開啟狀態下,模版會在compile
執行時額外拼接代碼的行信息,這樣在報錯時我們可以很方便定位是哪一行出的問題。
client
默認為false
,如果設置為true
則會在compile
函數中返回一個相對獨立的Function
。 主要是體現在一些內置函數的引用上。
open
設置開始的界定符。默認為<%
close
設置結束的界定符。默認為%>
模版對外暴露的API
官方文檔中寫的接口為:
compile
、render
。 確實。。其他幾個接口都不太常用,或者說,太難以使用,比如:parse
屬於一個半成品,renderFile
又只能在node
環境下使用。
clearCache
清除緩存,將之前內存中存儲的模版清空。 簡單粗暴的一個函數。。。老鐵,沒毛病。
exports.clearCache = function () { cache = {}; };
parse
參數 |
描述 |
---|---|
str |
要進行解析的模版字符串 |
options |
一系列的配置參數 |
解析模版字符串,將其轉換為可執行的JavaScript
代碼並返回。 P.S. 該函數的執行會返回一個JavaScript
腳本的字符串,我們可以通過new Function()
或者eval
(不推薦了)來執行該腳本獲得渲染好的字符串。
compile
參數 |
描述 |
---|---|
str |
要進行解析的模版字符串 |
options |
一系列的配置參數 |
函數會調用parse
,並將生成好的腳本塞進一個函數中,並將函數返回,我們可以通過調用該函數來獲得渲染好的字符串。
render
參數 |
描述 |
---|---|
str |
要進行解析的模版字符串 |
options |
一系列的配置參數 |
函數調用compile
,返回值即是渲染好的字符串。
renderFile
參數 |
描述 |
---|---|
path |
模版字符串存儲的路徑 |
options |
一系列的配置參數 |
fn |
獲取到文件後執行的回調函數 |
該函數會將path
取出,取出對應的文件,然後將文件的文本作為模版字符串傳入render
方法中。 fn
回調函數應遵守Error-First
的規則。(第一個參數為err
,後續參數為result
)
對外的API
除去clearCache
外的四個函數,是一個包含的關係,大致結構如下:
renderFile
[> readFile & callrender
]render
[> callcompile
& execute]compile
[> callparse
& wrap]parse
[> buildejs
template & return result]
一些完整的示例
倉庫中存放了一些各種使用姿勢的示例: https://github.com/Jiasm/ejs-examples