Introduction to Node.js packages: Part 1- How to create a npm package and setup a test suite
Wednesday, May 18, 2011 at 7:10PM OS => OS X 10.6.7
Node.js => v0.4.7
npm => 1.0.6
Terminal => bash
In this post I’ll explain how to create a node package complete with tests and documentation.
Step 0 - Install the pre-req’s
Note the env stats above. I used Homebrew to install Nodejs v0.4.7 and then followed the manual git clone and ‘sudo make install’ procedure for installing npm. I ran into some permission issues using the one liner on the nmp website. I’m not pro enough to tackle internal node install errors yet. The manual git checkout, sudo make install, worked just fine.
Step 1 - Some background
I suggest you take a look at this: http://howtonode.org/introduction-to-npm This is a good introduction to the node package management system. Pay close attention to the Development section. Note what the author says about creating an node package from the get-go, not as an after thought. I could not agree with this more. Let’s have some fun!
Step 2 - Create your package.json file
It’s a good idea to write most of your Node.js application as a node package. The node package system will help you manage dependencies and other project related tasks for you. You can reuse and share these packages through the npm registry. Also, a package is much easier to test than a full blown application. These points, plus the ease of the ‘npm link’ which links your live development changes into your local node env, gives you no excuse not to go the app-as-a-package route right from the start.
Every package has to have a few things; a name, a version, a description, an author, a repo home, etc… All this info has to be in a special format inside your package.json file. Thankfully there is a simple tool to set this up for you (interactively) called ‘npm init’.
First we create a folder for our project:
mkdir filecore cd filecore
Then we run the ‘npm init’ command and answer some questions.
npm init
After you finish, it will create the following structure for you. Yours will be different if you answer the questions differently.
{
"author": "Brian Chamberlain ",
"name": "filecore",
"description": "Manages the files and directories of a Naccelle project",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "git://github.com/breakpointer/filecore.git"
},
"main": "filecore.js",
"engines": {
"node": "~0.4.7" #<<== NOTE: There is no 'v' in this version number
},
"dependencies": {},
"devDependencies": {}
}
Note: I had to tweak the output of the ‘npm init’ script to remove the letter ‘v’ it was putting in the the “node” attribute. Prior to my edit, the output for that section was “~v0.4.7” which is not correct. “~0.4.7” is the proper format.
This is just a start for this file… there are a number of other options you can configure. See this page for more info: https://github.com/isaacs/npm/blob/master/doc/json.md
Step 3 - Basic package structure
If you note from the package.json file above we’ve stated that our “main” is something called “filecore”. It doesn’t have to match the name of your project but it does have to be where you actually want to mount your app.
You should create a file with the name you specified as your “main”. In my example I’ll create one called ‘filecore.js’. In this file you’ll have to “export” the methods that you want available to the consumers of your package. In other words, when you do something like:
var fc = require('filecore');
The variable ‘fc’ will have the methods attached to it which you export. See the code below.
// Requires go here
// var x = require('x');
// var y = require('y');
// ...etc..
exports.method_a = function(){
// do stuff here
}
exports.method_b = function(){
// do stuff here
}
Step 4 - Test driven development
I’m a big fan of test driven development. While I don’t always practice test-first development (because frankly, that kinda takes the fun out of hacking on some new code) but when I have solid idea of what I want a piece of code to do I’ll lay down some tests. A good test base can help propel your development and catch those “I swear I didn’t change anything and now it’s broke!” kinda errors that can pop up from time to time.
I’ve used Jasmine on other JS based projects and found it to have a nice syntax and having built in mocking is nice too. Here’s a link to the project: http://pivotal.github.com/jasmine/
For a Node.js version of Jasmine, see this page: https://github.com/mhevery/jasmine-node. It installs just like any other Node.js package. I installed it globally because I intend to use it on other projects (hence the ‘-g’ option)
npm install jasmine-node -g
In the git repo for the jasmine-node package there are some example spec files to help you get going. Here’s my current project tree:
..README ..package.json ..filecore.js ..spec/filecore_spec.js
And as far as the code is concerned here are the filecore.js and the filecore_spec.js files:
//filecore.js
exports.method_a = function(){
// do stuff here
return('a');
}
exports.method_b = function(){
// do stuff here
return('b');
}
//filecore_spec.js
var fc = require('../filecore.js');
describe('jasmine-node', function(){
it('should pass', function(){
expect(fc.method_a()).toEqual('a');
});
it('should pass', function(){
expect(fc.method_b()).toEqual('b');
});
});
These tests and code are very trivial but they make sure we’ve setup our Node.js module properly and that our test suite works.
When you run the test suite you should see the following:
brian$ jasmine-node spec Started .. Finished in 0.002 seconds 1 test, 2 assertions, 0 failures
* That’s all for this part. In Part 2 I will go through fleshing out the filecore module and how to package and publish your Node.js package.*
jasmine,
javascript,
node,
npm,
package,
spec | in
Node.js,
Programming,
Testing 
