位置背景與路徑
Yeoman 檔案工具的基礎概念是隨時都有兩個位置背景在磁碟中。這些背景是產生器最可能讀取與寫入的資料夾。
目的地背景
第一個背景是目的地背景。目的地是 Yeoman 用於佈建新應用程式的資料夾。這也是使用者的專案資料夾,大部分的佈建工作都會寫入此處。
目的地背景的定義是目前的作業目錄或含有 .yo-rc.json
檔案的最接近母資料夾。 .yo-rc.json
檔案定義 Yeoman 專案的根目錄。這個檔案讓使用者可以在子目錄中執行指令,並讓這些指令套用於該專案中。這確保了使用者端行為的一致性。
你可以使用 this.destinationRoot()
來取得目的地路徑,或使用 this.destinationPath('sub/path')
加入路徑。
// Given destination root is ~/projects
class extends Generator {
paths() {
this.destinationRoot();
// returns '~/projects'
this.destinationPath('index.js');
// returns '~/projects/index.js'
}
}
此外,你也可以使用 this.destinationRoot('new/path')
手動設定。但為了保持一致性,你最好不要變更預設目的地。
如果你想知道使用者從哪裡執行 yo
,你可以透過 this.contextRoot
取得路徑。這是在我們透過 .yo-rc.json
決定專案根目錄前的原始呼叫 yo
路徑。
範本背景
範本背景是儲存範本檔案的資料夾。通常,這是用於讀取與複製的資料夾。
範本背景預設為 ./templates/
。你可以使用 this.sourceRoot('new/template/path')
覆寫這個預設值。
你可以使用 this.sourceRoot()
取得路徑值,或使用 this.templatePath('app/index.js')
加入路徑。
class extends Generator {
paths() {
this.sourceRoot();
// returns './templates'
this.templatePath('index.js');
// returns './templates/index.js'
}
};
「記憶體」檔案系統
Yeoman 在覆寫使用者檔案時非常小心。基本上,每個寫入到現有檔案的內容,都會經過衝突解決流程。這個流程需要使用者驗證每個寫入檔案的檔案,並覆寫其內容。
此行為避免了不愉快的意外,並降低錯誤風險。但這也表示每個檔案都非同步寫入到磁碟中。
由於非同步 API 難以使用,因此 Yeoman 提供了一個同步檔案系統 API,其中每個檔案都寫入到 記憶體檔案系統 中,而且只在 Yeoman 執行完畢後才會寫入到磁碟中。
這個記憶體檔案系統會在所有 組成產生器 之間共用。
檔案工具程式
產生器會在 this.fs
中顯示所有檔案方法,這是 mem-fs editor 範例 - 務必針對所有可用方法查看 模組文件。
值得注意的是,儘管 this.fs
會顯示 commit
,但您不應在產生器中呼叫。Yeoman 會在執行循環的競合階段之後,在內部呼叫。
範例:複製範本檔案
以下是一個範例,我們想要複製並處理範本檔案。
考量 ./templates/index.html
的內容是
<html>
<head>
<title><%= title %></title>
</head>
</html>
然後我們會使用 copyTpl
方法複製檔案,同時以範本處理內容。 copyTpl
使用 ejs 範本語法。
class extends Generator {
writing() {
this.fs.copyTpl(
this.templatePath('index.html'),
this.destinationPath('public/index.html'),
{ title: 'Templating with Yeoman' }
);
}
}
產生器完成執行後,public/index.html
將包含
<html>
<head>
<title>Templating with Yeoman</title>
</head>
</html>
一個非常常見的場景是儲存使用者於 提示階段 的答案,並用於範本建立
class extends Generator {
async prompting() {
this.answers = await this.prompt([{
type : 'input',
name : 'title',
message : 'Your project title',
}]);
}
writing() {
this.fs.copyTpl(
this.templatePath('index.html'),
this.destinationPath('public/index.html'),
{ title: this.answers.title } // user answer `title` used
);
}
}
透過串流轉換輸出檔案
產生器系統允許您套用自訂濾鏡,於每個檔案寫入應用。自動美化檔案、標準化空白等,絕對都是有可能的。
透過 Yeoman 程序每個階段,我們會將每個修正後的檔案寫入磁碟。此程序會透過 乙烯 主體串流傳遞(類似於 gulp)。任何產生器作者都可以註冊 transformStream
來變更檔案路徑和/或內容。
透過 registerTransformStream()
方法註冊新的修改器。以下是範例
var beautify = require("gulp-beautify");
this.registerTransformStream(beautify({ indent_size: 2 }));
請注意,任何類型的所有檔案都會透過此串流傳遞。請確定任何轉換串流都會通過它不支援的檔案。類似 gulp-if 或 gulp-filter 的工具將有助於過濾無效類型並通過它們。
您基本上可以使用任何 gulp 外掛程式搭配 Yeoman 轉換串流,於寫作階段處理產生的檔案。
提示:更新現有檔案內容
更新預先存在的檔案並非總是項簡單的工作。執行此任務最可靠的方法是解析檔案 AST(抽象語法樹) 並編輯它。此解決方案的主要問題在於編輯 AST 可能是囉嗦且有點難以理解。
一些知名的 AST 解析器包括
- Cheerio,用於解析 HTML。
- Esprima,用於解析 JavaScript - 您可能會對 AST-Query 感到興趣,它提供較低層的 API 編輯 Esprima 語法樹。
- 對於 JSON 檔案,您可以使用原生
JSON
主體方法。 - Gruntfile Editor,用於動態修改 Gruntfile。
使用正規表示法解析程式碼檔案是一條危險的路徑,在這麼做之前,您應該先閱讀 這個 CS 人類學答案,並了解正規表示法解析的缺點。如果您選擇使用正規表示法而不是 AST 樹編輯現有檔案,請小心並提供完整的單元測試。 - 請務必不要中斷使用者的程式碼。