独自のYeomanジェネレーターを作成する

ジェネレーターは、Yeomanエコシステムの構成要素です。それらは、エンドユーザー向けのファイルを生成するためにyoによって実行されるプラグインです。

このセクションを読むことで、独自のジェネレーターを作成および配布する方法を学びます。

ジェネレーターの整理

Nodeモジュールとして設定する

ジェネレーターは、その核心部分において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では、2つの異なるディレクトリ構造が許可されています。利用可能なジェネレーターを登録するために、./generators/を調べます。

前の例は、次のように記述することもできます。

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

この2番目のディレクトリ構造を使用する場合は、package.jsonfilesプロパティがすべてのジェネレーターフォルダーを指していることを確認してください。

{
  "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は現在のディレクトリを.yo-rc.jsonファイルの場所に移動し、そこで要求されたジェネレーターを実行します。

Storageモジュールは、.yo-rc.jsonファイルを作成します。ジェネレーターからthis.config.save()を初めて呼び出すと、ファイルが作成されます。

したがって、ジェネレーターが現在の作業ディレクトリで実行されていない場合は、ディレクトリツリーのどこかに.yo-rc.jsonがないことを確認してください。

これからどこへ行く?

これを読んだ後、ローカルジェネレーターを作成して実行できるようになるはずです。

ジェネレーターの作成が初めての場合は、実行コンテキストと実行ループに関する次のセクションを必ずお読みください。このセクションは、ジェネレーターが実行されるコンテキストを理解し、Yeomanエコシステム内の他のジェネレーターとうまく構成されるようにするために不可欠です。ドキュメントの他のセクションでは、目標を達成するのに役立つYeomanコア内で利用可能な機能を紹介します。