In this tutorial, I provide complete instructions for creating a new Node.js module, writing the code in coffee-script, publishing it on GitHub, sharing it with other Node.js fellows through NPM, testing it with Mocha, Should and JsCoverage and integrating it to travis. Because of its simplicity, this module could also be used as a scaffolding to create your own modules. I will consider as a module best practices. Additionally, I recommend listening to this audiocast on GitHub about titled “a module authoring show”.

Let’s start by describing what we want to achieve. We will create a module made of a single function call hello that will return the string world. In the near future, I consider to publish this module on GitHub and share it on NPM. Here’s how, in CoffeeScript we will use it once completed:

The GIT repository

The first step is to create a new directory and initialise it as a Git repository.

Lot of people prefer to declare each file to ignore. I personnaly like to have Git ignore all hidden files starting with . with the exception of the git ignore file and the Travis declaration file which is covered later. Also ignored are the dependencies modules even if our example module doesn’t require any.

The layout

The code being written in CoffeeScript, it will be placed inside the “src” folder and generated into the “lib” folder. Tests are written inside the “test” folder. The documentation will be generated from the source code into the doc folder.

The “package.json” file

Now, we will create a package declaration file. This is a json file present at the root of your module and named “package.json”. Not all fields are of equal importance. The name and version fields are the most important and are required. They form together an identifier that is assumed to be completely unique.

Also worth of interest are the “description”, “keywords”, “homepage”, “bugs”, “author”, “contributors”, “engines”, “repository”, and “scripts” fields. The “bugs” field is here defined as a string but you could also create an object with the “url” and “email” fields inside. I found the email field only useful for popular projects which deserve a mailing list.

Three fields allow you to define your module dependencies which are “dependencies”, “devDependencies” and “optionalDependencies”. The module does not define any external dependency to run but we use coffee-script for development and mocha and should for testing. The main field define the entry point to your program when you call require('tutorial').

Finally we define a “test” script to run our test case by executing the command npm test.

The code

We are writing the code in CoffeeScript. the “.coffee” file is located in “./src/tutorial.coffee” and the generated JavaScript file is located in “./lib/tutorial.js”. Here’s how the “.coffee” file looks like:

The module.exports is what your script have access to when requiring a module. In our case, it is associated to a function which return the string “world” when called.

The command to generate the JavaScript is ./node_modules/.bin/coffee -b -o lib src/*.coffee.

Code coverage

We use JSCoverage to instrument our source code and measure code coverage in your test. You can read the install instructions or, on OSX, run brew install jscoverage if HomeBrew is installed.

The instrumented code will be generated to the ‘./lib-cov’. After running the command jscoverage --no-highlight lib lib-cov, a part of the newly generated file in ‘./lib-cov/hello.js’ should look like:

The instrumented code is called by the test. The mechanism is described below.

The test case

Our module is simple enough to justify a single test case. We use mocha to run the test and should is used for assertion. The test is located in “./test/hello.coffee”. Mocha rely on the describe and it function.

Notice how the tutorial module may be included from the ‘./src’ or the ‘./lib-cov’ directory. Set the environment variable “TUTORIAL_COV” to 1 with the command export TUTORIAL_COV=1 to run test coverage.

To run the test, you need to install mocha and should with npm install and execute the command ./node_module/.bin/mocha --compilers coffee:coffee-script. Mocha need the “compilers” argument to map “.coffee” file to the CoffeeScript compiler. Alternatively, you may create a “mocha.opts” file placed in your test folder with the content as “–compilers coffee:coffee-script”.

Note, when writing your mocha function, the next callback isn’t required in case you may run your test synchronously like in the test above.

The documentation

Some of my libraries, like “CSV”, “mecano” and “ron”, include a similar script that parse the comment of my source code and generate markdown out of it. I find this pattern quite usefull. At the time of this writing, I’m still in the process to externalise this source code in docgen and those libraries still include a “doc.coffee” script.

Most of the documentation will be generated but nothing should stop you to manually edit other markdown pages inside the doc folder.

The license

The license file must be present inside your project root directory and named “LICENSE” for NPM to discover it. Popular non-restrictive open source licenses used across the Node.js community are the the MIT license and the BSD license. I suggest you ready my article “About the new BSD license…” as there exist different versions of the BSD license based on the clause you wish to endorse.

The readme

Since our module is already well documented, there is no need to repeat the same information inside of the readme. I like to keep it bare simple, covering the following topics.

  • Short introduction
  • Usage instruction with a simple and optionally an advanced example
  • Note and migration instructions
  • Development information such as installation and how to run the tests
  • List of contributors

The make file

From the package declaration file, we’ve seen that the make file define a “test” command which use Mocha. We will also add a build command to compile the CoffeeScript file into a JavaScript file. Note that the “test”, “doc” and “coverage” commands will be preceded by the “build” command.

Travis

Travis CI is a hosted continuous integration service for the open source community. The idea is that any push request to GitHub will trigger a hook. What Travis does is to execute your tests on different virtual machine with various Node.js versions. The exact procedure is published on the Travis Getting Started page. After going to travis and signing-in with your GitHub OAuth, you activate which repository you want to integrate, then GitHub will ask you for granting read and write access and finally, you must include a “.travis.yml” at the root of your repository. The content of the file looks like:

As you can see, the file is written in YAML. Declaring the language as “node_js” tells Travis that it should execute the command npm test. The “node_js” property defines the different version of Node.js used to run the tests.

The example

It is a good practice to include a few samples. For this, a “./samples” directory could be created. For now, we will just create a “./samples/hello.js” file which look like the one in our article introduction, but in JavaScript. Not all our user code in CoffeeScript. We could later enrich the “samples” folder when our user asks usage related questions. Our “hello” sample looks like:

The marketing

Publishing your module on npm will create a dedicated page with information extracted from your package file, including your homepage. The url will be in the form of “https://npmjs.org/package/” followed by your module name.

Also, it is a good practice to add your own entry on the Node.js wiki module page which has been around since the first days of node, before NPM even existed.

The Node.js user mailing list accept module announcements. In such case, prefix your subject title with “[ANN]”.

There also exist a few blogs which may be happy to relay your module announcement.