天天看點

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

腳手架項目群組件初始化開發

将收獲什麼

  • ​ejs​

    ​ 模闆渲染
  • ​glob​

    ​ 檔案篩選
  • 項目标準安裝和自定義安裝
  • 元件庫初始化和安裝

主要内容

  • 腳手架安裝模闆功能架構設計
  • 腳手架模闆安裝核心實作
  • ​ejs​

    ​ 庫功能詳解
  • 腳手架安裝模闆功能開發
  • 元件模闆開發及腳手架元件初始化功能支援
  • 腳手架自定義初始化項目模闆功能開發

模闆功能架構設計

之前已經發過這個流程圖,下面來回顧一下,特别需要注意的是項目群組件的流程有一些差別。

準備階段

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

下載下傳模闆階段

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

安裝模闆階段

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

ejs 的三種用法

安裝 ​

​ejs​

npm i -S ejs      

編寫一些基礎代碼

const ejs = require('ejs')
const path = require('path')

// 定義模闆字元串
const html = '<div><%= user.name %></div>'

// 配置對象
const options = {}

// 資料
const data = {
  user: {
    name: '一尾流莺'
  }
}
const data2 = {
  user: {
    name: 'yiweiliuying'
  }
}      

再準備一個 ​

​template.html​

​ 檔案,内容如下

<div><%= user.name %></div>      

第一種用法

用于多次調用同一個 ​

​compile function​

​​ ,傳入不同資料。使用 ​

​ejs.compile​

​​ 生成 ​

​compile function​

​是比較消耗性能的,是以需要多次調用的時候,生成一個就行了。

// 傳回一個 compile  function , 用來解析 html 中的 ejs 模闆
const template = ejs.compile(html, options)

// 得到一個編譯後的模闆
const compiledTemplate = template(data)
const compiledTemplate2 = template(data2)

console.log('???????? ~ compiledTemplate', compiledTemplate);
console.log('???????? ~ compiledTemplate2', compiledTemplate2);      

可以看到模闆字元串已經被替換成資料了。

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

第二種用法

用于隻渲染一次模闆的時候

const renderedTemplate = ejs.render(html, data, options)
console.log('???????? ~ renderedTemplate', renderedTemplate);      

結果是一樣的。

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

第三種用法

第三種用法是對檔案進行編譯。

編譯檔案有兩種方式。

第一種,隻傳入三個參數,會傳回一個 ​

​Promise​

const renderedFile = ejs.renderFile(path.resolve(__dirname, 'template.html'), data, options)
console.log('???????? ~ renderedFile', renderedFile);      

可以看到是一個 ​

​Promise​

​ 對象。

【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

第二種,可以傳入第四個參數,回調函數。

ejs.renderFile(path.resolve(__dirname, 'template.html'), data, options, (err, file) => {
  console.log('???????? ~ file', file);
})      
【架構師(第十七篇)】腳手架之 ejs 和 glob 的使用

ejs 标簽的含義

寫畢設的時候用的是 ​

​art-template​

​​ 這一個模闆引擎,但是忘的差不多了,應該跟 ​

​ejs​

​ 文法差不多。

  • <%:​

    ​script​

    ​ 标簽,用于流程控制,不會輸出在頁面上
  • <%_:删除其前面的空格符
  • <%=:輸出資料到模闆(輸出是轉義​

    ​HTML​

    ​ 字元串)
  • <%-:輸出非轉義的資料到模闆
  • <%#:注釋标簽,不執行,不輸出内容
  • <%%:輸出字元串​

    ​<%​

  • %>:一般結束标簽
  • -%>:删除後序的換行符
  • -%>:将結束後的空格符删除

條件判斷

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>      

循環

<% for(var i =0;i<10;i++) {%>
    <div><%= user.name%></div>
<% } %>      

包含

通過 ​

​include​

​ 指令将相對于模闆路徑中的模闆片段包含進來。

<% for(var i =0;i<10;i++) {%>
    <div><%= user.name%></div>
<% } %>
<%- include('./footer.html', {user}); %>      

自定義分隔符

let ejs = require('ejs');
let users = ['geddy', 'neil', 'alex'];

// 單個模闆檔案
ejs.render('<?= users.join(" | "); ?>', {users: users},
    {delimiter: '?'});
// => 'geddy | neil | alex'

// 全局
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>', {users: users});
// => 'geddy | neil | alex'      

自定義檔案加載器

預設的檔案加載器是 ​

​fs.readFileSync​

​​,如果想要自定義它, 設定 ​

​ejs.fileLoader​

​ 即可。

let ejs = require('ejs');
let myFileLoader = function (filePath) {
  return 'myFileLoader: ' + fs.readFileSync(filePath);
};

ejs.fileLoader = myFileLoad;      

使用此功能,可以在讀取模闆之前對其進行預處理。

布局

​ejs​

​​ 并未對塊(​

​blocks​

​)提供專門的支援,但是可以通過包含頁眉和頁腳來實作布局,如下所示:

<%- include('header'); -%>
<h1>
  Title
</h1>
<p>
  My page
</p>
<%- include('footer'); -%>      

glob 的使用

​glob​

​ 是用來比對檔案路徑的,比對規則如下。

  • ​*​

    ​​ 比對任意 ​

    ​0​

    ​ 或 ​

    ​多個​

    ​ 任意字元
  • ​?​

    ​​ 比對任意 ​

    ​一個​

    ​ 字元
  • ​[...]​

    ​​ 若字元在中括号中,則比對。若以 ​

    ​!​

    ​ 或 ​

    ​^​

    ​ 開頭,若字元不在中括号中,則比對
  • ​!(pattern|pattern|pattern)​

    ​ 不滿足括号中的所有模式則比對
  • ​?(pattern|pattern|pattern)​

    ​​ 滿足 ​

    ​0​

    ​ 或 ​

    ​1​

    ​ 括号中的模式則比對
  • ​+(pattern|pattern|pattern)​

    ​​ 滿足 ​

    ​1​

    ​ 或 更多括号中的模式則比對
  • ​*(a|b|c)​

    ​​ 滿足 ​

    ​0​

    ​ 或 更多括号中的模式則比對
  • ​@(pattern|pat*|pat?erN)​

    ​​ 滿足 ​

    ​1​

    ​ 個括号中的模式則比對
  • ​**​

    ​ 跨路徑比對任意字元

安裝

npm i glob -S      
const glob = require('glob')

glob('**/*.js', {
  ignore: ['node_modules/**', 'webpack.config.js']
}, (err, file) => {
  console.log('???????? ~ err', err);
  console.log('???????? ~ file', file);
})