Quantcast
Channel: TechieDreams
Viewing all articles
Browse latest Browse all 21

Create and publish Yeoman Generator

$
0
0

In the previous tutorials we learnt what Gulp and Bower are and how they simplify WEB development process. Often with these tools installed in the project, we can only focus on writing the business logic. Yeoman allows you to generate such project structures with all the base features installed.

In this tutorial we learn:

1. What is ‘YOEMAN’?
2. How to set up the ‘yo’ Environment?
3. What is a Yeoman generator?
4. How to create our own generator?

What is ‘YEOMAN‘? :

YEOMAN – The web’s scaffolding tool for modern webapps: Its basically a tool which combines the ‘Build System’ and the ‘Package Manger’.
Popular options for build system are: ‘Gulp’ and ‘Grunt’. And Popular options for package management are ‘Bower’ and ‘Node’.
Yeoman, holding both the build system and package management tools together allows us to create a ‘generator‘, which can be used to produce a final project with the build system and package management tools installed.

How to set up the ‘yo’ Environment?:

1. Install node.js:

Install node: http://nodejs.org/download/ [for windows download .exe and for mac download the universal .pkg file]
2. Double click on the installer and follow the instructions to complete the installation.

OR

Optionally we can install node using the ‘homebrew’ package manager:
http://brew.sh/ – install homebrew package manager.
Mac – open terminal install, run the following to install ‘home brew’:

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

Once ‘home brew’ is installed, run the following to install ‘Node‘:

brew install node

Test:
npm -v
  : should display the version of node installed else try re-installing.

2. Install YEOMAN:

Install YEOMAN globally by opening terminal and run:

npm install -g yo

if it throws any error saying admin access, run the same command with sudo:

sudo npm install -g yo

Test:

yo -v
  : Should display the version of yeoman installed else try re-installing.

3. What is Yeoman generator?:

As discussed earlier yeoman is a package which can hold different tools like gulp, bower etc and will generate you a final project structure where you can use it directly with out thinking of setting up the environment.

There are many official Yeoman generators available. For any major frame work there are many generators available: A famous and official Angular yeoman generator is: ‘generator-angular

So this angular generator will provide you with the basic setup to create a angular project.
Lets see – how to run a Yeoman generator:

1. Setup ‘node’ and install ‘Yeoman’ as shown in the above lines.
2. Install yeoman generator globally: Terminal/command prompt run:

npm install -g generator-angular

3. Create a folder for your angular project. Terminal change directory to the project folder.

Run

yo angular
  optionally passing an App name:

yo angular [app-name]

Once the above command has successfully run, you will have your Base angular project setup.
So once we have installed the generator globally we can use ‘yo angular’ to create any number of angular projects, with out every time downloading it from server.

 

4. How to create our own generator?

We can always go for the official generators available, but yeoman optionally allows you to create your own Generator, where you can script your generator to generate a project structure according to your requirement. Not only you create a custom generator but you can always publish it to the world.

a) Generating a Generator using Yeoman Generator Generator:

Even more simplifying the process of generating the generator yeoman introduces ‘Yeoman Generator Generator‘, which provides you the base to create a custom generator. So if you just prefer to do everything manually you can check the official documentation on how to here: http://yeoman.io/authoring/index.html

Now will check how to run the Yeoman generator generator:

1. Install yeoman generator generator globally. Terminal/Command prompt, Run:

npm install -g generator-generator

Use sudo to run as Admin if the above one fails:

sudo npm install -g generator-generator

2. Create a folder for your Generator. Terminal change directory to the folder and Run:

yo generator

Yeoman will prompt you to enter your Github user name and base name for your generator..

Note ‘base name’ will be name after the ‘generator’ prefix: generator-name. generator will be auto prefixed so just give a unique base name. Ex: chanuyo will be base name and the final generator will be ‘generator-chanuyo’

Once you enter the base name and hit enter it will download the generator to the current directory.

Below is the screenshot for demonstration:

td_create_yo_gen

3. You will now find a folder with name: generator-yourbasename, in my case ‘generator-chanuyo’:
Following is the folder structure you will see:

td_yo_project_structure

4. Now you have a default generator ready. So before modifying it to add our custom features, we will test this base generator:

We can test it in two ways, directly form local by linking or by publishing to npm. We can also optionally create a Git project for the generator, we will also check how to link the git project.  So lets check the both ways:

1. Local test using npm link:

Navigate to the generator folder in terminal and Run:

npm link

That’s all your local generator has been symlinked globally and you can now run the generator.

Go to any folder to try the generator and Run:

yo [base name]

Ex: 

yo chanuyo

You can see the result of the generator in the current folder. For the basic generator they just added a folder and few files. You can customize how ever the result can be, we will discuss this at the end.

2. Publish to npm and optionally create a Git repository for the generator:

Once your generator is fully ready and if you feel it would be helpful to the world, then you can publish your generator by following the below steps:

Note: Here Creating a git repository for the generator is completely optional. If you don’t want a git repo just skip to step: 6 directly.

step 1: Create a Github account or If you already have one: Create a new repository with the same name as the generator we just created. Ex:

generator-chanuyo
 .

step 2: from the home page of the repository copy the ‘HTTPS clone URL’: In my case it is : https://github.com/chanusukarno/generator-chanuyo.git

And now create a new folder and terminal chanage directory to the folder, Run:

git clone <clone url>

Ex: 

git clone https://github.com/chanusukarno/generator-chanuyo.git

step 3: Now you will find a new folder inside the current folder called ‘generator-basename’:
In my case the folder is ‘generator-chanuyo’.

Terminal navigate to the folder and Run:

git status

If nothing goes wrong it will display no changes to commit.

So now we have our git project setup locally.

step 4: Copy the folder contents created by the generator to this git folder(replace if any). So now our local git repository folder should look the same as the one created by the generator refer the above folder structure screenshot.

step 5: Once we added the new files we need to commit and push them to the git to make the changes reflect on Git.

First add the files to be commited, terminal Run:

git add *

It will mark all the files to be committed. Now Run:

git commit -m "some commit message"

Now we have committed the files locally. The files are now ready to be pushed to server, Run:

git push origin master

Done! now the generator code have been pushed to Git. Refresh your git repository home page to see the changes.

Cool now we have our generator created on the Git!

step 6: The final step before using our generator as the other available generators is to publish the generator to node.

We do this by just running,

npm publish
 . Before that we need to add a user to publish. Terminal run:

npm adduser

Fill in the details and finish adding user. Below is the screenshot for reference:

td_create_yo_adduser

Now from the terminal run:

npm publish

This will now publishes your generator to the npm registry. So now we our own basic yeoman generator ready and available to the world.

Running our generator:
In my case i have published a generator called: ‘generator-chanuyo‘. From Terminal run:

npm install -g generator-chanuyo

OR to run as administrator run:

sudo npm install -g generator-chanuyo

We have ‘chanuyo’ generator installed globally. So now we can create any number project structures by just running 

yo chanuyo
 from the terminal:

yo chanuyo

Wohooo!! We just have created and published our own Yeoman Generator!

So we learnt how to create a base generator and publish it. Now will move on to:

How to Script your Generator:

YEOMAN generator-generator generated a base structure for our generator, now will check how to customise it and add our own features in the generator:

  1. Getting user inputs
  2. Creating the folder structure
  3. Copying files
  4. Adding custom templates
  5. Defining the Run tasks

Here i will take the generator which we created, angular-gulp-bower generator as the example to explain each one of the above:

So to start with, in yeoman every generator will have a folder with ‘index.js‘ (actual script for the generator goes here) and ‘templates‘ (to hold the files used by the generator) folder.

If you check the ‘index.js’ generated, it has a main object extended from the yeoman ‘Base‘ class. To start from scratch we will delete all the main object contents. So our index.js will look like this:

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


var AngularGulpBowerGenerator = yeoman.generators.Base.extend({
});

module.exports = AngularGulpBowerGenerator;

Also the index.js exports a object which will be used by yeoman to perform the tasks. We can extend our object from mainly two base classes: Base – in general we can use this class. NameBase – adds one optional parameter to the installation command:

Ex for NameBase:

syntax: 

yo <generatorname> <optional name>

Ex: 

yo angular-gulp-bower MySampleProject

Note: Name the files in the templates folder starting with underscore(_) just to differentiate the file from the final out files. Also yeoman will execute each of the tasks(functions) in the index.js one after other starting from the first, so we can name the functions with what ever gives a meaning to the task.

1. Getting user inputs:

Yeoman allows us to take some inputs from user when running a generator. Inputs like the Project Name can be prompted to the user and we can use them while generating the final project.

Example:

promptUser: function() {
        var done = this.async();
        // have Yeoman greet the user
        console.log(this.yeoman);

        var prompts = [{
                name: 'appName',
                message: 'Enter your project name?'
            }
        ];

        this.prompt(prompts, function(props) {
            this.appName = props.appName;
            done();
        }.bind(this));
    }

So all the prompts will go as array of objects with ‘name’ and ‘message’ and finally will pass this array to the prompt function of yeoman. The ‘prompt’ function has a callback where it gives the user inputs and we can store them in main context(this.appName) for future use.

2. Creating folder structure:

We can define the output projects folder structure using using yeoman’s file utility functions. Here we use

mkdir
  to create folders in the out put folder. Here is our final function to create the folder structure:
createFolders: function() {
        this.mkdir("app");
        this.mkdir("app/fonts");
        this.mkdir("app/images");
        this.mkdir("app/partials");
        this.mkdir("app/scripts");
        this.mkdir("app/scripts/controllers");
        this.mkdir("app/scripts/directives");
        this.mkdir("app/scripts/data");
        this.mkdir("app/scripts/filters");
        this.mkdir("app/scripts/services");
        this.mkdir("app/scripts/utility");
        this.mkdir("gulp");
    }

First create the base folder next the sub folder. The above example shows the folder structure used for my angular generator.

3. Copying files:

So Once we defined our project structure, we now can some files to these folders. Copy all the files which we want to copy to the out put folder to ‘templates’ folder. Here is my templates folder snapshot used for angular generator:

td_yo_templates

We can copy the files from the templates folder to the output by using

copy
  function of the yeoman. It will ask for two parameters, the source file name and the final output file name. Ex:
this.copy("_sampleFilter.js", "app/scripts/filters/sampleFilter.js");

4. Adding custom templates:

Also instead of directly just copying files from template directory to the output, we can optionally modify the file before copying it to the output folder:

Here we have got a name from the user to be used as the project name, So we need to add this name to the index.html and copy the resolved html to the output folder with the project name. Yeoman uses EJS styled templates to create placeholders which will be filled runtime.

So in the templates folder this is how our title tag looks like:

<title><%= site_name %></title>

and for example say user has entered ‘MySampleProject’ as project name then in the out put we will see the index.html title tag as:

<title>MySampleProject</title>

So to achieve the above we need to write the following code in the index.js:

var context = {
            site_name: this.appName
        };

        this.template("_index.html", "app/index.html", context);

So our final copyFiles function will look like this:

copyFiles: function() {
        this.copy("_gulpfile.js", "Gulpfile.js");
        this.copy("_package.json", "package.json");
        this.copy("_bower.json", "bower.json");
        this.copy("_main.css", "app/styles/main.css");
        this.copy("_.bowerrc", ".bowerrc");
        this.copy("_mainApp.js", "app/scripts/mainApp.js");
        this.copy("_gulp/_build.js", "gulp/build.js");
        this.copy("_gulp/_server.js", "gulp/server.js");
        this.copy("_gulp/_watch.js", "gulp/watch.js");
        this.copy("_gulp/_wiredep.js", "gulp/wiredep.js");
        this.copy("_sampleController.js", "app/scripts/controllers/sampleController.js");
        this.copy("_sampleDirective.js", "app/scripts/directives/sampleDirective.js");
        this.copy("_sampleService.js", "app/scripts/services/sampleService.js");
        this.copy("_sample.json", "app/scripts/data/sample.json");
        this.copy("_sampleFilter.js", "app/scripts/filters/sampleFilter.js");
        this.copy("_util.js", "app/scripts/utility/util.js");
        this.copy("_constant.js", "app/scripts/utility/constant.js");
        this.copy("_page1.html", "app/partials/page1.html");

        var context = {
            site_name: this.appName
        };

        this.template("_index.html", "app/index.html", context);
    }

5. Defining the Run Tasks: 

So finally to install all the node dependencies and the bower components in the output project, we need to initiate the node and bower tasks. Here is how we do it:

runNpm: function() {
        console.log("\n Done loading files! \nInstalling Node modules and Bower packages...\n");
        this.npmInstall("", function() {
            console.log("\n Done installing node modules!\n Run 'npm start' to build and serve the project");
        });
        this.bowerInstall("", function() {
            console.log("\n  Done installing bower Packages\n");
        });
    }

We used

npmInstall
  function to initiate node module installation and this method takes in two parameters, the first is the paths we can leave it empty and the second is the callback function which will be fired when all the node modules are installed. So we can use this callbacks to display user about the status of the installation. bowerInstall also works the same way.

Thats all for now! If you want to know more about customizing your generator and creating a Sub Generator, check out the official documentation.

 

 Subscribe Like and Share!

The post Create and publish Yeoman Generator appeared first on Techie Dreams.


Viewing all articles
Browse latest Browse all 21

Trending Articles