Writing a CLI tool using Node.js

In this post we would try to write a Node.js module from scratch and also publish it to NPM (Node Package Manager).

Before we start, we are just gonna have a look at things we need to get started:

  • GitHub repository: To store all the code and mantain versions
  • Grunt : Grunt is a great tool and it will help us get started with a project skeleton
  • An Idea: This is the most important thing, you should have a use case you want to solve with your module.
    • Try to build modules that are not yet available on NPM.
    • Don't re-invent the wheel

I will be trying to make a command line tool to convert csv files to json files.

For this i created a Github repo: (https://github.com/suroorwijdan/node-file-converter).

Getting Started

Clone the repository and run the following command grunt-init node. This will ask you few simple questions about the project you are going to create.

Once its done, open up package.json and verify the things that you entered while creating the project. This is the package.json in my case:

     {
       "name": "node-file-converter",
       "description": "A CLI tool for converting files to different 
       formats",
       "version": "0.0.1",
       "homepage": "https://github.com/suroorwijdan/node-file-converter",
       "author": {
       "name": "Suroor Wijdan",
       "email": "suroorwijdan@gmail.com"
    },
    "repository": {
       "type": "git",
       "url": "git@github.com:suroorwijdan/node-file-converter.git"
    },
    "bugs": {
       "url": "https://github.com/suroorwijdan/node-file-converter/issues"
    },
    "licenses": [
     {
       "type": "MIT",
       "url": "https://github.com/suroorwijdan/node-file-converter
       /blob/master/LICENSE-MIT"
     }
    ],
    "main": "lib/node-file-converter",
    "engines": {
      "node": ">= 0.8.0"
    },
    "scripts": {
      "test": "grunt nodeunit"
    },
    "devDependencies": {
      "grunt-contrib-jshint": "~0.6.4",
      "grunt-contrib-nodeunit": "~0.2.0",
      "grunt-contrib-watch": "~0.5.3",
      "grunt": "~0.4.2"
    },
    "keywords": []
    }

As we can see above, grunt has generated a node-file-converter.js file in the /lib directory. This is the main entry point for our module. You may change the main file to be something else depending on your choice.

In my case, i have put all my code in the file generated by grunt.

How do i make it work as a command:

To make your module to be available as a command you need to do the following two things:

  • add #!/usr/bin/env node on the top of your main file. This tells your machine how the file is to be executed.
  • add the following lines to the package.json file:
        "bin": {
            "nfc": 'lib/node-file-converter.js'
        }

The above lines will make the nfc command available to you when you install this module. You may just directly run npm link to install it locally on your machine to test. When you run this it will automatically install the dependencies needed.

How do we access the variables passed to nfc command:

This is very easy, all the arguments passed through command line are available in an array name process.argv. This is how it looks,

[ 'node', '/opt/node-v0.10.5-linux-x64/bin/nfc']

The first two indexes of the array are pre-filled with values that entertain the execution of the command. The actual arguments that are passed are accessible at indexes greater than 1, lets see below :

[ 'node', '/opt/node-v0.10.5-linux-x64/bin/nfc', 'suroor wijdan']

So basically, we do process.argv.slice(2) and assign it to some variable to only have the array of actual arguments passed by the user.

How do i publish on NPM?

Publishing on NPM is dead easy. You just need to have an account on NPM, if you don't than its just a matter of few seconds before you have one.

 To create a new account run the below command:

 npm adduser

 It will ask for username, password and email address

Now to publish your shiny new module on NPM, just the run this command from the project home:

    npm publish

And thats all, it will automatically create entries on the npm registry and link it to your account.

Thats all folks, you can access all the code of this module at the github url mentioned above. You are free to fork and contribute to make it cool.

Hope this helps! Next we will be looking at more of what Node.js has to offer.

comments powered by Disqus