ジェネレーターを実行するたびに、実際にはyeoman-environment
を使用しています。この環境は、UIコンポーネントから分離された基本システムであり、あらゆるツールで抽象化できます。yo
を実行すると、基本的にはYeomanコア環境の上にターミナルUIファサードを実行しているだけです。
基本
まず知っておくべきことは、環境システムがyeoman-environment
パッケージに含まれていることです。次のコマンドを実行してインストールできます。
npm install --save yeoman-environment
このモジュールは、インストールされているジェネレーターを取得、登録、実行するためのメソッドを提供します。また、ジェネレーターが使用するユーザーインターフェースアダプターも提供します。APIドキュメント全文(利用可能なメソッドの簡潔なリスト)を提供しています。
yeoman-environment
の使い方
簡単な使用例
詳細なトピックに移る前に、yeoman-environment
の簡単な使用例から始めましょう。
この例では、npm
がpackage.json
をスキャフォールディングするためのnpm init
コマンドを提供したいと仮定します。ドキュメントの他のページを読めば、ジェネレーターの作成方法をすでに知っているでしょう。そのため、すでにgenerator-npm
があると仮定します。それを呼び出す方法を見てみましょう。
最初のステップは、新しい環境インスタンスをインスタンス化することです。
var yeoman = require('yeoman-environment');
var env = yeoman.createEnv();
次に、後で使えるようにgenerator-npm
を登録します。ここでは2つのオプションがあります。
// Here we register a generator based on its path. Providing the namespace
// is optional.
env.register(require.resolve('generator-npm'), 'npm:app');
// Or you can provide a generator constructor. Doing so, you need to provide
// a namespace manually
var GeneratorNPM = generators.Base.extend(/* put your methods in here */);
env.registerStub(GeneratorNPM, 'npm:app');
必要な数のジェネレーターを登録できることに注意してください。登録されたジェネレーターは、環境全体で利用可能になります(たとえば、コンポーザビリティを可能にするため)。
この時点で、環境はnpm:app
を実行する準備ができています。
// In its simplest form
env.run('npm:app', done);
// Or passing arguments and options
env.run('npm:app some-name', { 'skip-install': true }, done);
これで完了です。このコードをbin
実行可能ファイルに配置するだけで、yo
を使用せずにYeomanジェネレーターを実行できます。
インストールされているジェネレーターを探す
しかし、ユーザーのマシンにインストールされているすべてのYeomanジェネレーターへのアクセスを提供したい場合はどうでしょうか?その場合は、ユーザーのディスクを検索する必要があります。
env.lookup(function () {
env.run('angular');
});
Environment#lookup()
は、Yeomanがインストールされているジェネレーターの検索を完了すると呼び出されるコールバックを受け取ります。見つかったすべてのジェネレーターは、環境に登録されます。
名前空間の競合が発生した場合、ローカルジェネレーターがグローバルジェネレーターをオーバーライドします。
登録されているジェネレーターに関するデータを取得する
Environment#getGeneratorsMeta()
を呼び出すと、ルックアップタスクが登録したメタデータを記述するオブジェクトが返されます。
各オブジェクトキーはジェネレーターの名前空間であり、値オブジェクトには次のキーが含まれています。
resolved
: ジェネレーターへの解決済みパスnamespace
: ジェネレーターの名前空間
例えば
{
"webapp:app": {
"resolved": "/usr/lib/node_modules/generator-webapp/app/index.js",
"namespace": "webapp:app"
}
}
注:#registerStub()
を使用して登録されたジェネレーターは、resolved
値として"unknown"
を持ちます。
カスタムユーザーインターフェース(UI)の提供
Yeomanは、IDE、コードエディターなどがジェネレーターの実行に必要なユーザーインターフェースを簡単に提供できるように、抽象化レイヤーとして*アダプター*を使用します。
アダプターは、ユーザーとのすべてのインタラクションを処理する役割を担うオブジェクトです。従来のコマンドラインとは異なるインタラクションモデルを提供したい場合は、独自のアダプターを作成する必要があります。ユーザーと対話するためのすべてのメソッドはこのアダプターを通過します(主に:プロンプト、ロギング、差分表示)。
デフォルトでは、Yeomanはターミナルアダプターを提供します。また、テストヘルパーは、プロンプトをモックし、出力をサイレンシングするテストアダプターを提供します。これらを独自の実装の参考として使用できます。
アダプターをインストールするには、yeoman.createEnv(args, opts, adapter)
の3番目のパラメーターを使用します。
アダプターは、少なくとも3つのメソッドを提供する必要があります。
Adapter#prompt()
質問と回答の機能を提供します(たとえば、yo
を起動すると、ユーザーに可能なアクションのセットがプロンプト表示されます)。そのシグネチャと動作は、Inquirer.jsのシグネチャと動作に従います。ジェネレーターがthis.prompt
を呼び出すと、呼び出しは最終的にアダプターによって処理されます。
Adapter#diff()
競合が発生し、ユーザーが古いファイルと新しいファイルの差分を要求したときに内部的に呼び出されます(両方のファイルの内容が引数として渡されます)。
Adapter#log()
これは、汎用出力用の関数とオブジェクトの両方です。提供するメソッドの完全なリストについては、lib/util/log.js
を参照してください。
実装例
yeoman-environment
を使用しているモジュール/プラグイン/アプリのリストを以下に示します。これらをインスピレーションとして使用できます。