Follow me if you want to grow your full-stack JavaScript skills with my screencasts and courses.

Yeoman generator

Resources

Creating a generator: http://yeoman.io/authoring/

Intro

Hey, my name is Hemanth and this is an episode on creating a new yeoman generator.

There are so many yeoman-generators out there, how about building your own?

That's what we're gonna do in the rest of this episode.

Setup

First up, and I realize this is extremely meta, we install the generator-generator, which we'll use to generate a generator! :)

terminal
  
  $ npm install -g yo generator-generator
  

Generate the generator

Now that we've got the generator installed, let's create a generator named generator-hello.

The first thing we do is create a folder for our generator, cd into it, and run the generator we installed earlier. I give it my username on github, and also a name for the generator.

terminal
  
  $ mkdir ~/tagtv/hello && cd $_
  $ yo generator

     _-----_
    |       |
    |--(o)--|   .--------------------------.
   `---------´  |    Welcome to Yeoman,    |
    ( _´U`_ )   |   ladies and gentlemen!  |
    /__A__\   '_____________'
     |  ~  |
   _'.__.'_
 ´   `  |° ´ Y `

  Create your own magical generator with superpowers!
  [?] Would you mind telling me your username on GitHub? hemanth
  [?] What's the base name of your generator? hello
     create package.json
     create .editorconfig
     create .jshintrc
     create .travis.yml
     create README.md
     create .gitattributes
     create .gitignore
     create app/index.js
     create app/templates/editorconfig
     create app/templates/jshintrc
     create app/templates/_package.json
     create app/templates/_bower.json
     create test/test-load.js
     create test/test-creation.js
     ....
     ....
  

Let's have a look at what this created for us by running the tree command.

terminal
  
  $ cd generator-hello

  $ tree # excluding node_module
  .
  ├── README.md
  ├── app
  │   ├── index.js
  │   └── templates
  │       ├── _bower.json
  │       ├── _package.json
  │       ├── editorconfig
  │       └── jshintrc
  ├── package.json
  └── test
      ├── test-creation.js
      └── test-load.js

  3 directories, 9 files
  

Now that we have the scaffold going, we type npm link in the generator-hello dir, this links your new generator to global node_modules.>

Let's check it out by running the yo command. Notice that the Hello generator is now avaliable in the list!>

terminal
  
  $ yo
  [?] What would you like to do? (Use arrow keys)
  ❯ Run the Generator generator (0.4.3)
    Run the Hello generator (0.0.0)
    Update your generators
    Install a generator
    Find some help
    Get me out of here!
  

Make it do something

The generator extends the Base generator of yeoman, which has init, askFor, app and projectfiles methods.

  • the app function takes care of creating the app dir that your generator scaffolds
  • the projectfiles function copies the required template files after they are processed
  • the askFor function care of prompting questions to the user
  • finally, the init function installs dependencies

The askFor function has a variable named prompts:

./app/index.js
  
  var prompts = [{
    type: 'confirm',
    name: 'someOption',
    message: 'Would you like to enable this option?',
    default: true
  }];
  

The user will be prompted on the CLI when they invoke your generator via yo. There are many prompt types avaliable for better U.

Now, let's edit the prompt from confirm to input:

./app/index.js
  
  var prompts = [{
    type: 'input',
    name: 'greet',
    message: 'Would you like to enable this option?',
    default: 'Yo! Wasup?'
  }];

  this.prompt(prompts, function (props) {
    this.greet = props.greet;

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

We modify the app method to create an app folder and copy our index.html file there.

./app/index.js
  
  app: function () {
    this.mkdir('app');

    this.copy('index.html','app/index.html');
    this.copy('_package.json', 'package.json');
    this.copy('_bower.json', 'bower.json');
  }
  

Where did this index.html file come from?

Well, it's expected in the template folder, let's create it now.

./templates/index.html
  
  <html>
   <head> </head>
   <body>
     <h1><%= props.greet%></h1>
    </body>
  </html>
  

Testing

Let's have a look at the tests for the generator, which is located in the test-creation.js file, in the test folder. We wanna verify that the index.html file is where we expect it to be after running the generator.

./tests/test-creation.js
  
  // add files you expect to exist here.
  'app',
  'app/index.html',
  'package.json',
  'bower.json',
  '.jshintrc',
  '.editorconfig'
  

Let's run the test.

terminal
  
  $ cd ~/labs

  $ mkdir hello && cd $_

  $ yo hello

       _-----_
      |       |
      |--(o)--|   .--------------------------.
     `---------´  |    Welcome to Yeoman,    |
      ( _´U`_ )   |   ladies and gentlemen!  |
      /__A__\   '_____________'
       |  ~  |
     _'.__.'_
   ´   `  |° ´ Y `

  You're using the fantastic Hello generator.
  [?] Would you like to enable this option? Yo! Wasup?
     create app/index.html
     create package.json
     create bower.json
     create .editorconfig
     create .jshintrc


  I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try running the command yourself.


  npm WARN package.json package@0.0.0 No description
  npm WARN package.json package@0.0.0 No repository field.
  npm WARN package.json package@0.0.0 No README data
  

Now open the index.html file, and you're presented with our newly created file!

Wrap up

That's it! Pretty powerful!

This was a very simple generator. Now go ahead and modify the files in the template dir as per your need and create some cool generators.

See you next time!