我正在构建一个自定义Yeoman生成器,它安装了许多预处理语言编译器,如CoffeeScript,LESS和Jade。在我的生成器创建的Gruntfile中,我有一个构建任务,可以编译所有内容。但是,在该构建任务至少运行一次之前,编译的HTML,CSS和Javascript文件不存在,如果我尝试在新建脚手架之后运行grunt watch / connect服务器,这可能会造成混淆。
让我的生成器在安装结束时运行Grunt构建步骤的最佳方法是什么?已经用于调用end
的{{1}}事件似乎是正确的地方,但我应该如何与Grunt沟通?
答案 0 :(得分:47)
如果您关注筹码,this.installDependencies
最终会一直向下https://github.com/yeoman/generator/blob/45258c0a48edfb917ecf915e842b091a26d17f3e/lib/actions/install.js#L36:
this.spawnCommand(installer, args, cb)
.on('error', cb)
.on('exit', this.emit.bind(this, installer + 'Install:end', paths))
.on('exit', function (err) {
if (err === 127) {
this.log.error('Could not find ' + installer + '. Please install with ' +
'`npm install -g ' + installer + '`.');
}
cb(err);
}.bind(this));
进一步追查此问题,this.spawnCommand
来自https://github.com/yeoman/generator/blob/master/lib/actions/spawn_command.js:
var spawn = require('child_process').spawn;
var win32 = process.platform === 'win32';
/**
* Normalize a command across OS and spawn it.
*
* @param {String} command
* @param {Array} args
*/
module.exports = function spawnCommand(command, args) {
var winCommand = win32 ? 'cmd' : command;
var winArgs = win32 ? ['/c'].concat(command, args) : args;
return spawn(winCommand, winArgs, { stdio: 'inherit' });
};
换句话说,在您的Generator代码中,您可以随时调用this.spawnCommand
,并将您希望终端运行的参数传递给它。如同this.spawnCommand('grunt', ['build'])
。
那么下一个问题是你把它放在哪里?线性思考,您只能相信grunt build
在安装完所有依赖项后才能工作。
来自https://github.com/yeoman/generator/blob/45258c0a48edfb917ecf915e842b091a26d17f3e/lib/actions/install.js#L67-69,
this.installDependencies
接受回调,因此您的代码可能如下所示:
this.on('end', function () {
this.installDependencies({
skipInstall: this.options['skip-install'],
callback: function () {
this.spawnCommand('grunt', ['build']);
}.bind(this) // bind the callback to the parent scope
});
});
试一试!如果一切顺利,您应该在新的this.spawnCommand
调用之上添加一些错误处理以确保安全。
答案 1 :(得分:15)
我使用了斯蒂芬的好答案,通过以下方式实现自定义事件以保持整洁。
MyGenerator = module.exports = function MyGenerator(args, options, config) {
this.on('end', function () {
this.installDependencies({
skipInstall: options['skip-install'],
callback: function() {
// Emit a new event - dependencies installed
this.emit('dependenciesInstalled');
}.bind(this)
});
});
// Now you can bind to the dependencies installed event
this.on('dependenciesInstalled', function() {
this.spawnCommand('grunt', ['build']);
});
};
答案 2 :(得分:3)
这个问题已经有点陈旧了,但如果有人错过了这个问题,我还是想补充这个问题。现在,安装后流程更容易实现。查看run loop并使用<article v-for="phase in phases" class="phase">
... Other content ...
<div v-for="role in filtered(phase.id) ">
<p>${role.title}</p>
</div>
</article>
方法,您可以在其中运行所有安装后的内容。