/ Javascript

Create and publish your first Node JS package

Creating a node.js package and further publishing it for other people to use it is pretty simple process. Through this post I shall walk through the process by creating a small library and publishing it.

Before diving into writing the code and creating the package, make sure you have node.js and npm installed. If not, you can follow the below process -

Install Node.js and npm

Install Node, npm in Ubuntu - 
sudo apt-get install nodejs
sudo apt-get install npm
sudo ln -s /usr/bin/nodejs /usr/bin/node

Mac users can use Homebrew
brew install node

Assuming node and npm is installed, lets now get into the core business.

configure NPM

This configuration step is completely optional but I prefer to do so. This saves a lot of my time. The below code sets your personal detail and every time you create a new package, these details will be automatically set.

npm set init.author.name "Prashant Bansal"
npm set init.author.email "prashantban@gmail.com"
npm set init.author.url "http://prashantb.me" 

Great, so now we have the personal details set.

Creating a node module

A Node/npm module is just an ordinary JavaScript file with the addition that it must follow the CommonJS module spec. Luckily, this is really not as complex as it sounds. Node modules run in their own scope so that they do not conflict with other modules. Node relatedly provides access to some globals to help facilitate module interoperability. The primary 2 items that we are concerned with here are require and exports. You require other modules that you wish to use in your code and your module exports anything that should be exposed publicly. For example:

var require = require('some_module');
module.exports = function() {
    console.log(require.doSomething());
}

In our demo, we are going to build a Linkedlist Library.This will be a simple library which will be able to create a Linkedlist datastructure and also be able to define needful functions. If you are preparing for Interviews with Tech companies, you should go through this library and also be able to create your own functions to do certain tasks like reversing a linked list or finding an element or removing it etc. What we need is to first create an empty repository in github.
If you do not want to create , you can very well clone my repository.

git clone git@github.com:prashantban/ll-js.git
cd ll-js

Next up, we shall start our node module. Its easy, just type -

npm init

This will initiate your node module and will ask certain questions. These will be part of your package.json file. You can follow my package.json file to know the key and value required.

{
  "name": "ll-js",
  "version": "0.1.0",
  "description": "JS Library for LinkedList",
  "main": "index.js",
  "scripts": {
    "test": "./node_modules/.bin/mocha --reporter spec"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/prashantban/ll-js.git"
  },
  "keywords": [
    "js",
    "linkedlist"
  ],
  "author": "Prashant Bansal <prashantban@gmail.com> (http://prashantb.me/)",
  "license": "MIT",  
  "bugs": {
    "url": "https://github.com/prashantban/ll-js/issues"
  }
}

More or less, your package.json will look similar. Now is the time to move into our main code file - index.js . Here is the initial code we need -

module.exports = (function() {

var Node,LinkedList;

Node = function (item) {
    this.item = item;
    this.next = null;
};

LinkedList = function () {
    this.head = new Node('head');
    this.size = 0;
};

LinkedList.prototype.insert = function(data) {
   if(this.find(data) === null) {
    	var cur_node = this.head;
        while (cur_node.next !== null) {
            cur_node = cur_node.next;
        }	
        var new_node = new Node(data);
        new_node.next = cur_node.next;
        cur_node.next = new_node;
        this.size += 1;
        return true;
    }
    else {
    	return false;
    }
};

LinkedList.prototype.show = function() {
    var cur_node = this.head;
    if(!cur_node.next) return '';
    var out = [];
    while (cur_node.next !== null) {
        out.push(JSON.stringify(cur_node.next.item));
        cur_node = cur_node.next;
    }
    var res = out.join(' --> ');
    return res;
};

return {
    LinkedList : LinkedList
};

})();

Full Library Code

Now is the time to write test cases. Node has a wonderful module named Mocha and Chai. As a beginner, it is probably the most easiest to write test cases in. Lets first install it in our library -

npm install mocha --save-dev
npm install chai --save-dev

Similar to index.js file, we also need a file where we could write our test cases. I have created a test folder and inside it I have put another index.js file where we will write all our test cases.

without explaining the code, since I feel it is self explanatory, here it is -

var should = require('chai').should(),
    ds = require('../index'),
    LinkedList = ds.LinkedList;

    describe('LinkedList' , function(){

		describe('init' , function(){
			it('should create a Linkedlist Instance' , function(){
				var obj = new LinkedList();
				obj.should.be.an('object');
				obj.size.should.equal(0);
				obj.head.item.should.equal('head');
				should.not.exist(obj.head.next);
			});
		});

		describe('show', function(){
			var emptylist, fullist;
			before(function() {
				emptylist = new LinkedList();
				fullist = new LinkedList();
				fullist.insert(1);
				fullist.insert(2);
				fullist.insert(3);
			});

			it('should create an emptylist', function() {
				emptylist.show().should.equal('');
			});

			it('should have only one element', function() {
				emptylist.insert(1);
				emptylist.show().should.equal('1');
			});

			it('should show 3 elements', function() {
				fullist.show().should.equal('1 --> 2 --> 3');
			});
		});

	});

Full Test Code

Now, to run the test cases, we only need to let our package.json file know about it. to do so, include the following in your package.json file -

"scripts": {
    "test": "./node_modules/.bin/mocha --reporter spec"
  },

and now simply run - npm test
The results should be similar to as following -

> ll-js@0.1.2 test /home/bansal/Desktop/Node-Sll/ll-js
> mocha --reporter spec

  LinkedList
    init
      ✓ should create a Linkedlist Instance
    show
      ✓ should create an emptylist
      ✓ should have only one element
      ✓ should show 3 elements
    remove
      ✓ should remove node with data as 3
      ✓ should remove first element
      ✓ should remove Last element
    insertAtHead
      ✓ should insert this data at head
      ✓ should show the data
    insert
      ✓ should insert this data at head
      ✓ should show the data
      ✓ should not allow insertion
    insertAtPosition
      ✓ should insert this data at head
      ✓ should show the data
      ✓ should not allow insertion
    Union
      ✓ should union the list and change the size
      ✓ should check for null of new list
    reverse
      ✓ should reverse the list
      ✓ should return false if empty or only 1 element is present


  19 passing (23ms)

Great, so now we have all our cases passed. We can be sure of our module now. All you need now is to make sure your git is up to date and has all updates. To do so, write the following lines -

git tag 0.1.0
git add .
git commit
git push origin master --tags

Publish to NPM

If you are confident that your package has none or very less issues, you could publish your code to NPM for other people to use it. In order to do so, simply write -

npm publish

once your package is up on npm, one can install it directly by typing -

npm install ll-js

Use the version management system of npm to provide updates. Following is the gist of the process -

  • Edit your code.
  • Update the code in github.
  • Update the version in package.json
  • publish using npm publish

Lastly, go find your module on the http://npmjs.org website and share it with friends. Here’s npm’s LL-JS page.