Search code examples
yeomanyeoman-generator

Splitting Yeoman prompts into multiple separate groups


how would one split a yeoman prompt into parts? I have a rather extended prompt that i'd like to split into parts with a title for each part.

CSS
- prompt1

HTML
-prompt 2

Something like this:

prompt1: function(){
  var done = this.async();
  condole.log('title 1');
  var prompts = [{
      name: 'prompt1',
      message: 'Prompt 1:',
    }]
},


prompt2: function(){
  var done = this.async();
  condole.log('title 2');
  var prompts = [{
      name: 'prompt2',
      message: 'Prompt 2:',
    }]
},

Thanks!


Solution

  • Update as @Deimyts notes in the comments, the original code stopped working. This is due to API changes in Inquirer.JS documented here.

    • The base API interface is now inquirer.prompt(questions).then(). There's no more callback function.
    • Any async question functions is taking a promise as return value instead of requiring this.async().

    In a nutshell, instead of using the old var done = this.async() API and resolving the prompt inside the callback with done() just return a promise from the prompting functions (see docs).

    prompt1: function() {
      this.log("HTML")
      return this.prompt([
          // configure prompts as before
        ]).then(function (answers) {
          // callback body as before, but no more calling done()
      }.bind(this));
    },
    

    For more details see @Deimyts answer below.


    Yeoman uses a run loop with certain predefined priorities that you can use to put your actions into. As mentioned in the ☞ docs you can group several methods at one priority. Here is a snippet to illustrate a generator with prompts split into two groups HTML and CSS:

    'use strict';
    
    var generators = require('yeoman-generator');
    
    module.exports = generators.Base.extend({
    
      constructor: function () {
        generators.Base.apply(this, arguments);
      },
    
      prompting: {
        prompt1: function() {
          this.log("HTML")
          var done = this.async();
          this.prompt([{
              type    : 'input',
              name    : 'foo',
              message : 'Foo',
            }, {
              type    : 'input',
              name    : 'bar',
              message : 'Bar'
            }], function (answers) {
              this.foo = answers.foo;
              this.bar = answers.bar;
              done();
            }.bind(this));
        },
    
        prompt2: function() {
          this.log("CSS")
          var done = this.async();
          this.prompt([{
              type    : 'input',
              name    : 'bam',
              message : 'Bam',
            }], function (answers) {
              this.bam = answers.bam;
              done();
            }.bind(this));
        }
      },
    
      configuring: function () {
        console.log(this.foo, this.bar, this.bam);
      }
    });
    

    Using this feature of Yeoman you could modularize your code even further, e.g. by putting your different prompts in separate code files and require / import them into your generator file. But basically the above snippet should do the trick.

    Let me know if that helps.