合成可能性とは、小さな部品を組み合わせて大きなものを作る方法です。Voltron®のようなもの
Yeomanは、ジェネレータが共通の基盤の上に構築するための複数の方法を提供します。同じ機能を書き直す意味はないため、ジェネレータを他のジェネレータ内で使用するためのAPIが提供されています。
Yeomanでは、合成可能性は2つの方法で開始できます。
- ジェネレータは、別のジェネレータと自身を合成することを決定できます(例:
generator-backbone
はgenerator-mocha
を使用します)。 - エンドユーザーが合成を開始することもできます(例:Simonは、SASSとRailsを使用したBackboneプロジェクトを生成したいと考えています)。注:エンドユーザーが開始した合成は計画されている機能であり、現在は利用できません。
this.composeWith()
composeWith
メソッドを使用すると、ジェネレータは別のジェネレータ(またはサブジェネレータ)と並行して実行できます。そのため、すべてを自分で行う代わりに、他のジェネレータの機能を使用できます。
合成する際には、実行コンテキストと実行ループを忘れないでください。特定の優先順位グループの実行では、合成されたすべてのジェネレータはそのグループの関数を実行します。その後、次のグループに対して繰り返されます。ジェネレータ間の処理順序は、composeWith
が呼び出された順序と同じです。実行例を参照してください。
API
composeWith
は2つのパラメータを受け取ります。
generatorPath
- 合成するジェネレータを指す完全なパス(通常はrequire.resolve()
を使用)。options
- 合成されたジェネレータが実行された後に渡すオプションを含むオブジェクト。
peerDependencies
ジェネレータと合成する場合
this.composeWith(require.resolve('generator-bootstrap/generators/app'), {preprocessor: 'sass'});
require.resolve()
は、Node.jsが指定されたモジュールをロードする場所からのパスを返します。
注:1.0より古いバージョンのyeoman-generator
に基づいてジェネレータにarguments
を渡す必要がある場合は、options.arguments
キーとしてArray
を提供することで実行できます。
推奨される方法ではありませんが、composeWith
にジェネレータの名前空間を渡すこともできます。その場合、YeomanはそのジェネレータがpeerDependencies
として、またはエンドユーザーシステムにグローバルにインストールされているかどうかを調べようとします。
this.composeWith('backbone:route', {rjs: true});
ジェネレータクラスとの合成
composeWith
は、最初の引数としてオブジェクトを受け取ることもできます。オブジェクトには、次のプロパティが定義されている必要があります。
Generator
- 合成するジェネレータクラスpath
- ジェネレータファイルへのパス
これにより、プロジェクト内で定義されたジェネレータクラス、または他のモジュールからインポートされたジェネレータクラスと合成できます。composeWith
への第2引数としてoptions
を渡すと、期待通りに動作します。
// Import generator-node's main generator
const NodeGenerator = require('generator-node/generators/app/index.js');
// Compose with it
this.composeWith({
Generator: NodeGenerator,
path: require.resolve('generator-node/generators/app')
});
実行例
// In my-generator/generators/turbo/index.js
module.exports = class extends Generator {
prompting() {
this.log('prompting - turbo');
}
writing() {
this.log('writing - turbo');
}
};
// In my-generator/generators/electric/index.js
module.exports = class extends Generator {
prompting() {
this.log('prompting - zap');
}
writing() {
this.log('writing - zap');
}
};
// In my-generator/generators/app/index.js
module.exports = class extends Generator {
initializing() {
this.composeWith(require.resolve('../turbo'));
this.composeWith(require.resolve('../electric'));
}
};
yo my-generator
を実行すると、次の結果になります。
prompting - turbo
prompting - zap
writing - turbo
writing - zap
composeWith
の呼び出しを逆にすることで、関数呼び出しの順序を変更できます。
npmで公開されている他のパブリックジェネレータと合成できることに注意してください。
合成可能性のより複雑な例については、generator-generator(generator-nodeで構成されています)を参照してください。
依存関係またはpeerDependencies
npmは3種類の依存関係を許可します。
dependencies
は、ジェネレータに対してローカルにインストールされます。使用される依存関係のバージョンを制御するための最適なオプションです。これが推奨されるオプションです。peerDependencies
は、ジェネレータと並んで、兄弟としてインストールされます。たとえば、generator-backbone
がgenerator-gruntfile
をピア依存関係として宣言した場合、フォルダツリーは次のようになります。├───generator-backbone/ └───generator-gruntfile/
devDependencies
は、テストと開発ユーティリティ用です。ここでは必要ありません。
peerDependencies
を使用する場合は、他のモジュールも要求されたモジュールを必要とする可能性があることに注意してください。特定のバージョン(または狭いバージョンの範囲)を要求することで、バージョン競合が発生しないように注意してください。Yeomanでは、peerDependencies
を使用する場合は、常に利用可能なバージョン以上の(>=)または任意の(*)バージョンを要求することをお勧めします。例:
{
"peerDependencies": {
"generator-gruntfile": "*",
"generator-bootstrap": ">=1.0.0"
}
}
注:npm@3以降、peerDependencies
は自動的にインストールされなくなりました。これらの依存関係をインストールするには、手動でインストールする必要があります。npm install generator-yourgenerator generator-gruntfile generator-bootstrap@">=1.0.0"