思ってることってこんなもんだよ
はじめよう - Yeomanジェネレータの作成

何かを作りたい際に、ゼロから自分で作っていくのは、単純に大変な作業です。何か土台的なものがあって、自分でやりたいことだけを追記していければ、それに越したことはありません。

Yeoman は、さまざまな土台を作ってくれるツールです。 yo というコマンドを打ち込んでプロジェクトの雛形を作成した経験のある方は多いと思いますが、まさに yo が Yeroman です。 yo generator-name と打ち込むことで、ジェネレータが呼び出され、対話形式でいくつかの質問に答えるだけで、土台となるファイル群を生成させることが可能です。

そのジェネレータは、自作することも可能です。僕も、とあるジェネレータを自分で作ってみたくなりました。Yeoman のウェブサイトには、じぇねれーたのつくりかたはが複数ページに渡って説明されています。勉強の意味も兼ねて、日本語訳を作ってみました。

今回は、 Getting Started です。


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

このセクションを読むことで、あなた自身のジェネレータの作り方と配布方法について学ぶことになります。

注意: 私達は、彼ら自身のジェネレータを作り始めるユーザを助けるために、 generator-generator を作りました。以下のコンセプトを理解した際には、あなた自身のジェネレータを作り始めるために、気軽にそれを使ってください。

あなたのジェネレータを組織する

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" を含まなければならず、repo は、私達の generators page によってインデックスされた説明を持っている必要があります。

あなたは、依存ライブラリとして 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.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モジュールとしてはまだ利用可能ではありません。グローバルモジュールは、作成され、そしてローカルにシンボリックリンクが張られます。ここでは、それがあなたのやりたいことです。

コマンドライン上で、あなたのジェネレータプロジェクトのルート( 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コアの中で利用可能な機能性を提示します。