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*框架層出不窮,ReactAngularVue,當然這應該也是未來幾年的趨勢了,但是這些大都是前端運行時進行渲染,動態的生成HTML。 (React是有着服務端渲染的解決方案,為了解決SEO的問題) 但是EJS這類的模版引擎是不依賴於宿主語言環境的,只要是JavaScript即可,也就是說可以用於server端(node.js)直接渲染,返回給前端渲染好的頁面。(這個在大部分後台頁面的開發中還是需要的) 當請求某個鏈接時,直接將渲染完成的頁面呈現給用戶,主要的作用有兩點:

  1. 避免了代碼都存在前端,被某些惡意用戶看到。
  2. 對搜索引擎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>&lt;hello /&gt;</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

官方文檔中寫的接口為:compilerender。 確實。。其他幾個接口都不太常用,或者說,太難以使用,比如: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 & call render] render [> call compile & execute] compile [> call parse & wrap] parse [> build ejs template & return result]

一些完整的示例

倉庫中存放了一些各種使用姿勢的示例: https://github.com/Jiasm/ejs-examples