私は最初のYeomanジェネレーターを作成しています。これは、ユーザーにさまざまな入力を求め、その応答に基づいて条件付きでファイルを作成します。ユーザー入力に基づいてサブルーチン(Yeomanサブジェネレーターの場合もあります)を呼び出し、それに引数を渡すことができる必要があります。
名前付き関数(自動的には実行されない)を使用する理由は、ユーザーの応答によって複数の関数を組み合わせて呼び出す場合と、関数を単独で実行する場合があるためです。
私が試したこと:
ユーザーが要求した場合にのみファイルのセットを作成するので、サブジェネレーターが最適な方法であると考えました。しかし、条件付きで呼び出して、ユーザーが入力したものを渡すのに問題があります。 hookFor
を使用しようとしましたが、アサーションエラーが発生します:_hookFor must be used within the constructor only
_。 (デフォルトで実行したくないので、this.Prompt(prompts, function (props)
からサブジェネレーターを呼び出しています)。
質問:
ユーザーが(プロンプトを介して)要求した場合にのみルーチンを呼び出し、そのルーチンにユーザーが指定した情報を渡すにはどうすればよいですか?
あなたが親切に答えてくれるなら、私が何か明白なことを試みたと思い込まないでください;-)。
2つのサブジェネレーター(blog-serverとblog-client)を持つジェネレーター_generator-blog
_(BlogGenerator)があるとしましょう。
_app\index.js
client\index.js
server\index.js
_
したがって、_yo blog
_を実行するとき、ユーザーにいくつかのオプションを要求し、(オプションで)サブジェネレーターを実行する必要がありますか?
サブジェネレーターを実行するには、this.invoke("generator_namespace", {options: {}})
を呼び出す必要があります。渡した2番目の引数には、options
フィールドを含めることができます。これはジェネレーターに渡されるオプションオブジェクトです。
App\index.js内:
_BlogGenerator.prototype.askFor = function askFor() {
var cb = this.async();
// have Yeoman greet the user.
console.log(this.yeoman);
var prompts = [{
name: 'appName',
message: 'Enter your app name',
default: 'MyBlog'
}, {
type: 'confirm',
name: 'createServer',
message: 'Would you like to create server project?',
default: true
}, {
type: 'confirm',
name: 'createClient',
message: 'Whould you like to create client project?',
default: true
}];
this.Prompt(prompts, function (props) {
this.appName = props.appName;
this.createServer = props.createServer;
this.createClient = props.createClient;
cb();
}.bind(this));
}
BlogGenerator.prototype.main = function app() {
if (this.createClient) {
// Here: we'are calling the nested generator (via 'invoke' with options)
this.invoke("blog:client", {options: {nested: true, appName: this.appName}});
}
if (this.createServer) {
this.invoke("blog:server", {options: {nested: true, appName: this.appName}});
}
};
_
Client\index.js:
_var BlogGenerator = module.exports = function BlogGenerator(args, options, config) {
var that = this;
yeoman.Base.apply(this, arguments);
// in this.options we have the object passed to 'invoke' in app/index.js:
this.appName = that.options.appName;
this.nested = that.options.nested;
};
BlogGenerator .prototype.askFor = function askFor() {
var cb = this.async();
if (!this.options.nested) {
console.log(this.yeoman);
}
}
_
PDATE 2015-12-21:invoke
の使用は非推奨になり、composeWith
に置き換える必要があります。しかし、それはそれほど簡単ではありません。 invoke
とcomposeWith
の主な違いは、サブジェネレーターを制御する機能がなくなったことです。それらを使用して宣言することしかできませんでした。
上記のmain
メソッドは次のようになります。
_BlogGenerator.prototype.main = function app() {
if (this.createClient) {
this.composeWith("blog:client", {
options: {
nested: true,
appName: this.appName
}
}, {
local: require.resolve("./../client")
});
}
if (this.createServer) {
this.composeWith("blog:server", {
options: {
nested: true,
appName: this.appName
}
}, {
local: require.resolve("./../server")
});
}
};
_
また、置き換えられた_yeoman.generators.Base
_を_yeoman.Base
_に削除しました。
2015-04アップデート:yeoman apiには、ジェネレーターをリンクするための推奨メソッドとしてthis.composeWith
が含まれるようになりました。
ジェネレーターを分離し、「メインジェネレーター」を使用する場合、ジェネレーターを一緒に構成するときに、考えられるすべての実行シナリオ、条件チェック、プロンプトをカバーできます。実行コンテキストループが役立ちます。構成されたジェネレーターに構成を渡すには、.composeWith('my-genertor', { 'options' : options })
のoptions
を使用します。
.composeWith
を使用すると、優先グループ関数(例:prompting
、writing
...)がすべてのジェネレーターに対して実行され、次に次の優先グループが実行されます。 generatorAの内部から.composeWith
をgeneratorBに呼び出す場合、実行は次のようになります。例:
ジェネレーターA.prompting =>ジェネレーターB.prompting =>ジェネレーターA.writing =>ジェネレーターB.writing
異なるジェネレーター間の実行を制御したい場合は、 http://yeoman.io/authoring/composability.html#order に書かれているように、それらを一緒に構成する「メイン」ジェネレーターを作成することをお勧めします。 :
// In my-generator/generators/turbo/index.js
module.exports = require('yeoman-generator').Base.extend({
'prompting' : function () {
console.log('prompting - turbo');
},
'writing' : function () {
console.log('prompting - turbo');
}
});
// In my-generator/generators/electric/index.js
module.exports = require('yeoman-generator').Base.extend({
'prompting' : function () {
console.log('prompting - zap');
},
'writing' : function () {
console.log('writing - zap');
}
});
// In my-generator/generators/app/index.js
module.exports = require('yeoman-generator').Base.extend({
'initializing' : function () {
this.composeWith('my-generator:turbo');
this.composeWith('my-generator:electric');
}
});