---
title: Creating a generator for DoneJS applications
description: Creating a generator for DoneJS applications
image: https://www.bitovi.com/hubfs/donjs-banner.jpg
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting)
- ![Project Management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project Management](https://www.bitovi.com/services/agile-project-management-consulting)
- ![Product Design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product Design](https://www.bitovi.com/services/product-design-consulting)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting)
- [Design systems](https://www.bitovi.com/services/axure-figma-migration)
- [React](https://www.bitovi.com/services/frontend/react-consulting)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about delivering products and solving problems.
  
  ](https://www.bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships)
- [![Academy](https://www.bitovi.com/hubfs/icon%20-%20academy%20(4).svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse or contribute to our community
  
  ](https://www.bitovi.com/open-source)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

 April 13, 2016

# Creating a generator for DoneJS applications

 Creating a generator for DoneJS applications

![The Bitovi Team](https://www.bitovi.com/hubfs/TheBitoviTeam%20(1).png)

 The Bitovi Team

Share:

[![Twitter](https://www.bitovi.com/hubfs/limbo-generated/_astro/twitter-white.os3xLc3C_Z2nW4or.svg) ](https://twitter.com/intent/tweet?text=) [![Reddit](https://www.bitovi.com/hubfs/limbo-generated/imgs/icons/reddit.png) ](http://reddit.com/submit?url=)

The JS ecosystem is vast and we will never be able to support every JavaScript tool out there. However, we do want to make it simple for other open source developers to make those add-ons, and make it easy for others in the DoneJS community to use them. This is where DoneJS's generator generator comes in. It can be used to create modules that add functionality to an existing DoneJS application.

If you have used `donejs add nw` or `donejs add cordova` to create a [desktop- or mobile version](https://donejs.com/Features.html#section=section_iOS_Android_andDesktopBuilds) of your application you already used a DoneJS generator. Generators are [npm](https://www.npmjs.com/) modules that provide a [Yeoman](http://yeoman.io/) generator that adds functionality to your application.

In this article you will create your own version of [donejs-jshint](https://www.npmjs.com/package/donejs-jshint), a DoneJS generator that adds [JSHint](http://jshint.com/), a JavaScript code quality tool and an [.editorconfig](http://editorconfig.org/) file which helps text editors and IDEs to define and maintain a consistent coding style. It will also update the `npm test` script to run JSHint with our tests.

1. [Create the project on GitHub](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-create)
2. [Initialize the repository as a new DoneJS generator](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-init)
3. [Set up continuous integration with Travis CI](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-ci)
4. [Add .jshintrc and .editorconfig template files](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-templates)
5. [Implement the generator functionality](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-implement)
6. [Test the functionality manually](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-test)
7. [Write unit tests for the generator](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-unit)
8. [Publish the plugin to npm](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-npm)
9. [Show it off to the world](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications#generator-show)

You can find the code in the [donejs-jshint](https://github.com/donejs/donejs-jshint) repository. A video walkthrough of this article is available here:

We can run the generator with:

```
$ donejs add jshint
```

Currently it will only ask if we want to use spaces or tabs and to overwrite the `package.json` to add the npm scripts for JSHint:

![DoneJS generator](https://www.bitovi.com/hubfs/Imported_Blog_Media/Screen-Shot-2016-03-09-at-2_47_43-PM.png)

> **Note:** Since `donejs-jshint` already exists we will use `donejs-<username>-jshint` with `<username>` being your GitHub username for the remainder of this article. Once published it can then be used as `donejs add <username>-jshint`.

## Setting up

### Creating the project on GitHub

We will use [GitHub](https://github.com) to host the code for the project which makes it easy for others to contribute and to automatically run the tests in [continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) which we will enable later.

If you don't have an account yet, go to [GitHub](https://github.com/join) to sign up and follow [the help](https://help.github.com/articles/set-up-git/) on how to set it up for the command-line `git`. Once completed, create a new repository from your dashboard.

Calling the repository `donejs-<username>-jshint` and initializing it empty (without any of the default files) looks like this:

![generator-repository](https://www.bitovi.com/hubfs/Imported_Blog_Media/generator-repository1.png)

After creating the repository, clone it into a new folder:

```
$ git clone git@github.com:<username>/donejs-<username>-jshint.git
$ cd donejs-<username>-jshint
```

### Initializing the project

To initialize a new generator you will need DoneJS version 0.9.0+ installed globally. To check your DoneJS version run

```
$ donejs --version
```

To install DoneJS or to get the latest version run:

```
$ npm install donejs -g
```

In the `donejs-<username>-jshint` folder we can now initialize a new generator, very similar to a new DoneJS application, like this:

```
$ donejs add generator
```

The generator will ask several question that should be answered as follows:

- For the project name you can just confirm the default by pressing enter
- For the GitHub username or organization enter the GitHub username where the repository has been created
- All other fields can also be answered with the default or the information you would like to use

Once all done, the final prompt looks similar to this:

![generator-init](https://www.bitovi.com/hubfs/Imported_Blog_Media/generator-init.png)

Now the generator will initialize the default layout and install all its dependencies.

### Setting up Travis CI

When the installation has completed, make sure everything got set up properly by running:

```
$ npm test
```

This will run some basic generator tests and output the result on the console.

This command can also be used to automatically run the tests on a [continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) server. There are many open source CI servers, the most popular being [Jenkins](https://jenkins-ci.org/), and many hosted solutions like [Travis CI](https://travis-ci.org/).

We will use Travis CI as our hosted solution because it is free for open source projects. It works with your GitHub account which it will use to sign up. Once signed in, go to `Accounts` (in the dropdown under you name) to enable the `donejs-<username>-jshint` repository:

![generator-travis](https://www.bitovi.com/hubfs/Imported_Blog_Media/generator-travis.png)

You may have to click the *"Sync account"* button for the repository to show up. Now, every time we push to GitHub the tests will run automatically. We can do so with our initial commit:

```
$ git add . --all
$ git commit -am "Initial commit"
$ git push origin master
```

If you now go `https://travis-ci.org/<your-username>/donejs-<username>-jshint/builds` you will see the build running and eventually turn green (which will update the badge that got added in the `readme.md` file).

## Adding the configuration files

Now we can add the files that our generator should produce. All file templates will be put in the `default/templates/` folder.

### .jshintrc

First, add a `default/templates/.jshintrc` file which contains [options for JSHint](http://jshint.com/docs/options/):

```
{
  "node": true,
  "esnext": true,
  "bitwise": true,
  "camelcase": true,
  "curly": true,
  "eqeqeq": true,
  "immed": true,
  "indent": 2,
  "latedef": "nofunc",
  "newcap": false,
  "noarg": true,
  "regexp": true,
  "undef": true,
  "unused": true,
  "strict": false,
  "trailing": true,
  "smarttabs": true,
  "white": false
}
```

### .editorconfig

Next add a `default/templates/.editorconfig` file like this:

```
; Unix-style newlines
[*]
end_of_line = LF
indent_style = <%= indent_style %>
trim_trailing_whitespace = true
```

All files support [EJS](http://www.embeddedjs.com/) placeholders. Here, `<%= indent_style %>` will be used for the user choice of using whitespaces or tabs. Finally, remove `defaults/templates/file.js` since we won't be using it.

## Implementing the generator

For the most part, DoneJS generators are simply [Yeoman](http://yeoman.io/) generators so everything documented for [writing your own Yeoman generator](http://yeoman.io/authoring/) also applies here. For the user choice of tabs vs. spaces also refer to the chapter about [interacting with the user](http://yeoman.io/authoring/user-interactions.html).

### Adding the generator functionality

Our generator needs to ask if we want to use spaces or tabs and then copy the `.jshintrc` and `.editorconfig` files over to their final destination. We also want to add an `npm run jshint` script to the `package.json` and make sure that JSHint runs during `npm test`. The complete generator at `default/index.js` looks like this:

```
var generator = require('yeoman-generator');
var _ = require('lodash');

module.exports = generator.Base.extend({
  initializing: function () {
    // Read the original package.json
    this.pkg = this.fs.readJSON(
      this.destinationPath('package.json'), {}
    );

    // Maintain a list of all files we want to copy over
    this.files = [
      '.editorconfig',
      '.jshintrc'
    ];
  },

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

    // Create a prompt setting the `indent_style` property
    // to `tab` or `space`
    this.prompt([{
      type: 'list',
      name: 'indent_style',
      message: 'What indentation style do you want to use?',
      default: 'tab',
      choices: [
        {
          name: 'Tabs',
          value: 'tab'
        },
        {
          name: 'Spaces',
          value: 'space'
        }
      ]
    }], function (answers) {
      this.props = answers;
      done();
    }.bind(this));
  },

  writing: function () {
    var pkg = this.pkg;

    // Update `package.json` with the `jshint` command
    // and update the `test` script
    pkg.scripts = _.extend(pkg.scripts, {
      test: 'npm run jshint && ' + 
        _.get(pkg, 'scripts.test',
          'echo "No tests specified"'),
      jshint: 'jshint ' + 
        _.get(pkg, 'system.directories.lib',
          'src') + 
        '/. --config'
    });

    // Write to `package.json` and format accordingly
    // This will prompt you to overwrite
    var indent = this.props.index === 'tab' ? '\t' : '  ';
    this.fs.writeJSON('package.json', pkg, null, indent);

    // Install jshint as a development dependency
    this.npmInstall([ 'jshint' ], { saveDev: true});

    // Got through every file and copy it
    this.files.forEach(function(file) {
      this.fs.copyTpl(
        this.templatePath(file),
        this.destinationPath(file),
        this.props
      );
    }.bind(this));
  }
});
```

That's it. Now we have a fully functional generator and can give it a try in a DoneJS application.

### Manual testing

When running `donejs add <generatorname>` DoneJS will

- Check if `donejs-<generatorname>` is installed locally
- If not install it from NPM
- Then run the generator at `default/index.js`

If we want to test our generator without publishing it to npm first we can link it instead. In the generator folder run:

```
$ npm link
```

Then go into your test DoneJS application directory:

```
$ cd ../place-my-order
$ npm link donejs-<username>-jshint
```

Now we can run

```
$ donejs add <username>-jshint
```

### Writing a unit test

Yeoman also comes with some tools for [testing generators](http://yeoman.io/authoring/testing.html). The test we initially ran with `npm test` makes sure that `default/templates/file.js` gets written. Since we deleted that file, update the test at `test/index.js` to verify that it wrote the files we want with the content we expect:

```
var path = require('path');
var helpers = require('yeoman-test');
var assert = require('yeoman-assert');

describe('donejs--jshint', function() {
  before(function(done) {
    // Run the generator in a temprorary directory
    helpers.run(path.join(__dirname, '../default'))
      .inTmpDir()
      // Mock the user input by setting
      // `indent_style` to `tab`
      .withPrompts({
        'indent_style': 'tab'
      }).on('end', done);
  });

  // Verify that `.jshintrc` got written
  // and has some content
  it('created .jshintrc', function() {
    assert.file(['.jshintrc']);
    assert.fileContent('.jshintrc',
      /"latedef": "nofunc"/);
  });

  // Verify that `.editorconfig` got written
  // with `indent_style` set to our selection
  it('.editorconfig with indent_style', function() {
    assert.file(['.editorconfig']);
    assert.fileContent('.editorconfig',
      /indent_style = tab/);
  });

  // Make sure that `package.json` got updated
  // with the `jshint` npm script
  it('update package.json', function() {
    assert.jsonFileContent('package.json', {
      scripts: {
        jshint: 'jshint src/. --config'
      }
    });
  });
});
```

Now we can see all tests passing when running:

```
$ npm test
```

## Publishing the plugin

### Making a pull request

Although we are working on the generator by ourselves for now, [GitHub pull requests](https://help.github.com/articles/using-pull-requests/) are a great way to keep track of our progress and to make sure that all tests are passing. In the plugin folder run:

```
$ git checkout -b generator-functionality
$ git add . --all
$ git commit -m "Implementing JSHint and editorconfig generator"
$ git push origin generator-functionality
```

And then create a new pull request by going to `https://github.com/<username>/donejs-<username>-jshint` which will now show an option like this:

![generator-pr](https://www.bitovi.com/hubfs/Imported_Blog_Media/generator-pr.png)

Once you created the pull request, you will see a `Some checks haven’t completed yet` message that will eventually turn green:

![generator-pull-request](https://www.bitovi.com/hubfs/Imported_Blog_Media/generator-pull-request.png)

Now you can click the "Merge pull request" button. Then in the console, checkout the *master* branch and pull down the latest changes with:

```
$ git checkout master
$ git pull origin master
```

### Publishing to npm

For others to be able to use your generator via `donejs add <generatorname>` have to pulish it to [npm](http://npmjs.org). [Create a new account](https://www.npmjs.com/signup) and then log in via

```
$ npm login
```

[Semantic versioning](http://semver.org/) is a great way to communicate new features and breaking changes. The generated plugin already comes with the release scripts to publish new versions according to the `major.minor.patch` schema. In our case to publish an initial version `0.1.0` we can run

```
$ donejs release:minor
```

Now version `0.1.0` of the generator is available and everybody can use it through

```
donejs add <username>-jshint
```

## Show it off

Once you published your generator, let the world know about it. [Tweet @donejs](https://twitter.com/donejs) and post it in the [DoneJS forums](http://forums.donejs.com/) and the [DoneJS chat](https://gitter.im/donejs/donejs). Those are also great places to get quick help with any questions.

[![Tag for open source](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) open source ](https://www.bitovi.com/blog/topic/open-source)

 Previous Post

![](https://www.bitovi.com/hs-fs/hubfs/injection.jpg?height=117&name=injection.jpg) [ Simplify your Unit Tests with Dependency Injection for JavaScript Modules ](https://www.bitovi.com/blog/dependency-injection-for-javascript-modules)

  

 Next Post

![AJAX fixtures for JavaScript](https://www.bitovi.com/hs-fs/hubfs/AJAX%20fixtures%20for%20JavaScript.png?height=117&name=AJAX%20fixtures%20for%20JavaScript.png) [ AJAX fixtures for JavaScript ](https://www.bitovi.com/blog/ajax-fixtures-javascript)

```json
{
  "@context" : "http://schema.org",
  "@type" : "Organization",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "Libertyville",
    "addressRegion" : "IL",
    "postalCode" : "60048",
    "streetAddress" : "1134 Pine Tree Lane "
  },
  "alternateName" : "Bitovi",
  "areaServed" : {
    "@type" : "GeoCircle",
    "geoMidpoint" : {
      "@type" : "GeoCoordinates",
      "latitude" : "41.8781",
      "longitude" : "87.6298"
    },
    "geoRadius" : "5000 km"
  },
  "description" : "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
  "email" : "contact@bitovi.com",
  "image" : "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
  "logo" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
  "mainEntityOfPage" : {
    "@id" : "https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications",
    "@type" : "WebPage",
    "description" : "Creating a generator for DoneJS applications"
  },
  "naics" : "541511",
  "name" : "Bitovi Web App Consulting",
  "sameAs" : [ "https://www.facebook.com/BitoviLLC/", "https://twitter.com/bitovi", "https://www.linkedin.com/company/bitovi" ],
  "telephone" : "312-620-0386",
  "url" : "http://bitovi.com"
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "The Bitovi Team"
  },
  "dateModified" : "January 4, 2017, 4:56:27 PM",
  "datePublished" : "2016-04-13 22:02:09",
  "description" : "Creating a generator for DoneJS applications",
  "headline" : "Creating a generator for DoneJS applications",
  "image" : {
    "@type" : "ImageObject",
    "url" : "http://cdn2.hubspot.net/hubfs/2171535/donjs-banner.jpg"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```