调用的 Yeoman 子生成器不提示

Invoked Yeoman sub generator doesn't prompt

我想从我的主生成器中调用一些子生成器并让它们使用提示来获取它们自己的信息。我当前的实现在调用子生成器的提示步骤的同时执行主生成器的写入步骤,但我想执行以下步骤:

  1. 主生成器提示步骤
  2. 调用子生成器的提示步骤
  3. 写入主生成器的步骤
  4. 写入调用子生成器的步骤

我的主生成器是这样的:

'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  initializing: function () {
    this.pkg = require('../package.json');
  },

  prompting: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'Welcome to the neat ' + chalk.red('DockerSetup') + ' generator!'
    ));

    // Check for usage of redis, postgres and mysql subgenerators
    this.prompt([
    {
      type: 'input',
      name: 'subApplications',
      message: 'Enter the names of the sub-apps comma seperated'
    }], function (props) {
      this.subApplications = props.subApplications.length ? props.subApplications.split(',') : [];


    // Run subgenerators

    this.subApplications.forEach(function(name) {
      this.composeWith('docker-setup:sub-application', { args: [name] });
    }.bind(this));

      done();
    }.bind(this));
  },

  writing: function () {
    this.fs.copyTpl(
      this.templatePath('_Readme.md'),
      this.destinationPath('Readme.md')
    );
  }
});

这是我的副发电机

'use strict';
var yeoman = require('yeoman-generator');

module.exports = yeoman.generators.NamedBase.extend({
  initializing: function () {
    this.log('You called the DockerSetup subgenerator with the argument ' + this.name + '.');
  },

  prompting: function () {
    // Assume that the sub-apps are one level under this with same name

    this.prompt([
    {
      type: 'list',
      name: 'mainTech',
      message: 'Which is the main technology used?',
      choices: ['rails', 'yii', 'frontend']
    }, {
      type: 'checkbox',
      name: 'additionalTechnologies',
      message: 'Which technologies are used in this subapp?',
      choices: ['redis', 'postgres', 'mysql']
    }], function (props) {
      this.mainTech = props.mainTech;
      this.additionalTechnologies = props.additionalTechnologies;


      // This is done here, because if it's in the writing part it gets called before the prompt
      var path = this.destinationPath('fig.yml'),
          file = this.readFileAsString(path),
          content;

      switch(this.mainTech) {
        case 'rails':
          content = 'content';
        break;

        case 'yii':
        break;

        case 'frontend':
        break;
      }

      this.additionalTechnologies.forEach(function (tech) {
        content += ('    - ' + tech);
      });

      file += content;
      this.write(path, file);

      done();
    }.bind(this));
  }
});

在您真正完成该子生成器中的提示之前,您不应该调用 done() 函数。实际上,您可以在将工作分派给子生成器后立即继续执行。相反,您应该只异步调用 done()(因为它是大多数时候使用 async/done 的用例)。

为此,我相信您可以将 composeWith 命令与 .on 链接起来:

this.subApplications.forEach(function(name) {
      this.composeWith('docker-setup:sub-application', { args: [name] })
          .on('end',function(){
                        done();
                    });
    }.bind(this));

'end' 事件在每个 yo 进程结束时发出,根据 base.js 第 358 行)