撰寫自己的 Yeoman 產生器

產生器是 Yeoman 生態系統的組成部分。它們是由 yo 執行的外掛程式,可為最終使用者產生檔案。

在閱讀此區段時,您將會學會如何建立和散布自己的產生器。

整理您的產生器

設定為 Node.js 模組

產生器在核心上是一個 Node.js 模組。

首先,建立一個資料夾,您會在其中撰寫自己的產生器。此資料夾必須命名為 generator-name(其中 name 是您的產生器名稱)。這一點很重要,因為 Yeoman 仰賴檔案系統來尋找可用的產生器。

進入產生器資料夾後,建立一個 package.json 檔案。此檔案是 Node.js 模組清單。您可以透過從命令列執行 npm init,或手動輸入下列內容來產生此檔案

{
  "name": "generator-name",
  "version": "0.1.0",
  "description": "",
  "files": [
    "generators"
  ],
  "keywords": ["yeoman-generator"],
  "dependencies": {
    "yeoman-generator": "^1.0.0"
  }
}

name 屬性必須加上 generator- 的字首。keywords 屬性必須包含 "yeoman-generator",而存放區必須具有說明,才能由我們的 產生器頁面 索引。

您應確定將最新版本的 yeoman-generator 設定為相依關係。您可以透過執行下列指令來做到這一點: npm install --save yeoman-generator

files 屬性必須是您的產生器所使用的一組檔案和目錄。

根據需要,加入其他 package.json 屬性

資料夾樹狀結構

Yeoman 的功能仰賴您整理目錄樹狀結構的方式。每個次產生器都包含在自己的資料夾中。

當您呼叫 yo name 時所使用的預設產生器是 app 產生器。這必須包含在 app/ 目錄中。

次產生器(於您呼叫 yo name:subcommand 時使用)儲存在與次指令完全相同的資料夾中。

在一個範例專案中,目錄樹狀結構可能如下所示

├───package.json
└───generators/
    ├───app/
    │   └───index.js
    └───router/
        └───index.js

此產生器將顯示 yo nameyo name:router 命令。

Yeoman 允許兩種不同的目錄結構。它會在 ./generators/ 中尋找可用的產生器,以進行註冊。

前一個範例也可以改寫如下

├───package.json
├───app/
│   └───index.js
└───router/
    └───index.js

如果您使用此第二個目錄結構,請確定在您的 package.json 中針對所有產生器資料夾指向 files 屬性。

{
  "files": [
    "app",
    "router"
  ]
}

擴充產生器

一旦擁有此結構,就該撰寫實際的產生器了。

Yeoman 提供一個您可以擴充以實作自己的行為的基本產生器。此基本產生器會新增您期望的大部分功能,以簡化您的工作。

在產生器的 index.js 檔案中,以下是擴充基本產生器的方式

var Generator = require('yeoman-generator');

module.exports = class extends Generator {};

我們會將擴充產生器指派給 module.exports,使其能提供給這個生態系統。這就是我們 在 Node.js 中匯出模組的方法

覆寫建構函式

有些產生器方法只能在 constructor 函式內呼叫。這些特殊方法可以做一些事情,像是設定重要的狀態控制,而無法在建構函式外執行。

若要覆寫產生器建構函式,請加入建構函式方法,如下所示

module.exports = class extends Generator {
  // The name `constructor` is important here
  constructor(args, opts) {
    // Calling the super constructor is important so our generator is correctly set up
    super(args, opts);

    // Next, add your custom code
    this.option('babel'); // This method adds support for a `--babel` flag
  }
};

加入自己的功能

加入原型中的每個方法都會在呼叫產生器之後執行,而且通常是按順序執行。不過,就像我們在下一段會看到的,某些特殊方法名稱會觸發特定的執行順序。

讓我們加入一些方法

module.exports = class extends Generator {
  method1() {
    this.log('method 1 just ran');
  }

  method2() {
    this.log('method 2 just ran');
  }
};

稍晚時候我們執行產生器時,你會在主控台看到這些列的記錄。

執行產生器

執行到這邊為止時,你已經建立了一個好用的產生器。下一步就是執行它,看看是否可行。

由於你是在本地開發產生器,所以它還不是全球 npm 模組。可以使用 npm 建立全球模組然後連結到本機模組。以下是你要執行的步驟

在命令列,從產生器專案的根目錄 (在 generator-name/ 資料夾),輸入

npm link

這會安裝你的專案相依模組,然後將全球模組連結到你的本地檔案。在 npm 執行完畢之後,你就能呼叫 yo name,而且你應該會在終端機看到前面定義的 this.log被呈現出來。恭喜你,你剛剛建立了你的第一個產生器!

尋找專案根目錄

在執行產生器時,Yeoman 會依據執行資料夾的內容找出一些資訊。

最重要的是,Yeoman 會在目錄樹中搜尋 .yo-rc.json 檔案。如果找到了檔案,Yeoman 會將檔案的位置視為專案根目錄。在幕後,Yeoman 會將目前目錄變更為 .yo-rc.json 檔案的位置,然後在那邊執行要求的產生器。

儲存模組會建立 .yo-rc.json 檔案。第一次從產生器呼叫 this.config.save() 時,就會建立檔案。

因此,如果你的產生器沒有在目前的工作目錄執行,請確認目錄樹中某處沒有存在 .yo-rc.json

後續步驟

在讀完本篇文章後,你應該能建立本機產生器然後執行。

如果你第一次撰寫產生器,絕對應該閱讀下一段關於 執行內文和執行迴圈 的內容。在本段了解產生器執行的內文非常重要,而且可以確保它和其他 Yeoman 生態系統中的產生器會組成良好的效果。文件中的其他部分會說明 Yeoman 核心提供的功能,能協助你達成目標。