Command line utilities are becoming increasingly part of a web developers tooling arsenal. In my previous post (Writing a Command Line Utility using Node) I talked about the steps you could take to write your first command line utility using Node. As a followup to this I thought it would be good to go through some useful modules you can add to your utility and other extras you might want to add to make your Node CLI even better.

Commanding your Node CLI arguments with Commander.js

One of the most useful features of a command line utility is the ability for it to accept arguments from the user. These can vary significantly from the most simple utility that accepts one argument to a more complex utility which accepts lot of arguments.

In our previous tutorial we achieved this through reading the process.argv array. Our original code being

var userArgs = process.argv.slice(2); var value1 = parseInt(userArgs[0]); var value2 = parseInt(userArgs[1]);

This fine for a small little utility that adds two numbers together however this could potentially get quite messy for more complicated command line utilities. This is where Commander.js excels at making your life easier.

Our first step to use Commander.js with our project is to install it using npm

npm install commander --save-dev

After we have installed commander, we now need to use require to include it in our project.

var program = require('commander');

With commander in place we can now replace

var userArgs = process.argv.slice(2);

with

program .version('0.1.0') .option('--number1 ', 'specify the first number to add together',Number) .option('--number2 ', 'specify the second number to add together',Number) .parse(process.argv);

To retrieve our arguments we can now access them using program.number1 and program.number2 , this means we will need to update the values we reference to reference these new values.

var answer = program.number1 + program.number2;

Now if we test our utility we now need to reference the option we want to pass a value to so the command now becomes

calc --number1 20 --number2 20

which should result in

40

As an added bonus, our users will now be able to use --help to see all the arguments that our utility accepts.

This is just skimming on the surface of what commander.js is able to offer, to find out more information visit the commander.js website.

Underscore.js, the utility belt for your Node CLI

Underscore.js is a utility belt library which can be used on both the frontend and with node. Underscore.js is also the most popular libary to use with node.

For our simple calculator example, currently if the user enters a string instead of a number the result from the utlity is NaN (not a number). To fix this we can use Underscore.js to help us to validate whether the result is in fact a number and if it isn’t we will let the user know they need to enter numbers.

The first step is for us to install Underscore.js into our project

npm install underscore --save-dev

Once done we will then need to get Underscore.js by using require , we will add this directly after the require we have included for commander.js.

var _ = require('underscore');

We will then replace our existing console.log(answer) and calculation logic with

if(_.isUndefined(program.number1) || _.isUndefined(program.number2)){ console.log('Please check your arguments, check --help for details'); } else{ if(_.isNaN(program.number1) || _.isNaN(program.number2)){ console.log('Please only enter numbers'); } else{ answer = program.number1 + program.number2; console.log(answer); } }

The first step of this uses underscore to check if either of the values is undefined , if it is, an error message is displayed to the user. The next step is to check if the numbers entered are in fact numbers, if they are not another error message will be displayed. Finally if 2 numbers have been entered a result is calculated and then shown to the user.

This is of course a very simple example of how Underscore.js can be used to make your life easier.

Help your users to help themselves use your CLI

If you are familiar with the command line you will likely know of the man command which allows you to view manuals for different command line utilities, for example if you enter man ls it will load the manual for the ls command.

We can do this with Node command line utilities as well by creating a man file and adding it to our package.json file.

Getting started with man

For our manual we will use our existing README.md file, to enable this to work as a manual using the man command we will need to convert the README.md file into the correct format. For this we will use a tool called marked-man which will take our README.md file and give us our lovely manual.

Our first step is to install marked-man.

npm install marked-man -g

Once this is installed we can simply run the command to generate our manual (please note the folder doc will need to exist otherwise you will get an error).

marked-man README.md > doc/calc.1

With our man document prepared we can now add this to our package.json file, this is done by adding an extra item to the JSON object called

man

with the value set to an array of files that make up your manual.

"man" :[ "./doc/calc.1" ]

With this added we now need to update the npm link to our plugin by running.

npm link

We should now be able to view our new manual in the command line using

man calc

Summary

There are a lot of modules available which will help you to enhance both the features and the usability of your command line utilities. The NPM registry is a fantastic resource for finding modules that you can use. Through using NPM modules we can not only save time but we can also be more consistent with how other command line utilities have been developed.

Credits

I based this post partially on some comments on a Reddit post of the original article. In particular ISV_Damocles offered some good suggestions which I then researched to put this piece together.

Are you looking for your next role? I work as an Lead Engineer at RVU where we are currently looking for Full Stack software engineers based in our London office. Find out more

Please enable JavaScript to view the comments powered by Disqus.