在Yeoman生成器完成后,同步执行命令行操作

我正在构build一个Yeoman生成器,完成之后我想执行一些命令行操作,如'npm install','bower install'和'grunt less'。 我使用spawnCommand为此,我嵌套使用事件侦听器的所有操作,以同步执行它们。 但是,为了避免这种无休止的嵌套,我正在寻找一个更清洁的实现,使其易于扩展。 完美的,我想有一个命令的数组(如['npm install','grunt install','less:dev']),并通过正确的错误检测同步处理。

// Install npm packages this.spawnCommand('npm', ['install']) .on('exit', function (err) { if (err) { this.log.error('npm package installation failed. Please run \'npm install\' and \'bower install\'. Error: ' + err); } else { // Install bower packages this.spawnCommand('bower', ['install']) .on('exit', function (err) { if (err) { this.log.error('bower package installation failed. Please run \'bower install\'. Error: ' + err); } else { this.spawnCommand('grunt', ['less']) .on('exit', function (err) { if (err) { this.log.error('Less compilation failed. Please run \'grunt less:dev\'. Error: ' + err); } else { } }.bind(this)); } }.bind(this)); } }.bind(this)); 

像这样的东西? (未经testing):

 this.processTask = function (task) { this.spawnCommand(task.cmd, task.args) .on('exit', function (err) { if (err) { this.log.error('task failed. Error: ' + err); } else { this.emit('nextTask'); } }); }; this.on('nextTask' function(){ var next = this.tasks.shift(); if (next){ this.processTask(next); } else { console.log('we are done'); } }.bind(this)); //preparing the list of tasks: this.tasks = []; this.tasks.push({cmd: 'npm', args:['install']}); this.tasks.push({cmd: 'bower', args:['install']}); this.tasks.push({cmd: 'grunt', args:['less']}); //start first task this.processTask(this.tasks.shift()); 

我使用从Node.js的execSync似乎工作,例如:

 var child_process = require('child_process'); var result = execSync('grunt less'); 

Node.js 0.12和io.js 1.10支持execSync:

 child_process.execSync(command[, options]) 

并返回“Buffer | String来自命令的stdout”,这可能是一个错误代码。 API文档。

关于同步API的背后故事 。

你可以创build一个像init.sh这样的脚本,并将你需要按顺序运行的命令放在里面,如:

 #!/usr/bin/env bash npm install your-funky-command gulp something-special gulp 

…然后无论你需要把spawnCommand代码(我在end方法中),添加somehting像这样:

  var done = this.async(); this.spawnCommand('sh', ['init.sh'], /* maybe cwd? {cwd: 'src'} */) .on('close', done); 

不漂亮或者什么都行,但是很明显。


或者,如果您需要一个命令只在prev成功时运行,请执行以下操作:

 #!/usr/bin/env bash npm install \ && your-funky-command \ && gulp something-special \ && gulp 

(奖金的好处是,现在你的应用程序初始化逻辑不再与哟。)