Some ways to parse command line interface options in node.js

When making a node.js project that is to one extent or another a command line tool, there is often a need to parse options that may be given from the command line when using the tool. In this post i will be breefly covering some options for quickly getting this over with, and continuing with what really matters when making your node.js cli tool.

1 - what to know

This is a post on how to parse commands from the command line in a node.js project. This is not a getting started post on node.js, or javaScript in general. I assume that you have at least some background on these things, and are not researching how to handle this aspect of making command line tools with node.js.

2 - Some npm packages for parsing arguemnts

There are many npm packages that can be installed into a node.js project with npm install to add a dependency for quickly parsing command arguments from the command line, into a object that can be worked with. Many of these projects add additional useful features that allow for defining default values, and what to do for each sub command. In most cases this is best as it helps to save time when making a complex project, however there is also process.argv as well in node.js where the raw array of options are stored.

2.1 - commander

By far one of the most popular solutions for option parsing commander allows for quick option parsing, and also allows for defining commands.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env node
let prog = require('commander'),
path = require('path'),
pkg = require(path.join(__dirname, 'package.json'));
prog
.version(pkg.version || '0.0.0', '-v, --version')
.option('-a, --answer', 'the answer')
.parse(process.argv);
if (prog.answer) {
console.log(42);
} else {
console.log(prog);
}

2.2 - yargs

be sure to check out Yargs as it is a great solution for an option parser. In addition to being a great solution for just parsing what is at process.argv into a workable object for me, it also allows for me to set up commands that are a great way of defining the logic of one or more commands that are to happened when my cli tool is called.

For example I can set up a default command that will log a basic usage example, and then one or more additional commands that actually do something.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
let yargs = require('yargs'),
klaw = require('klaw'),
path = require('path'),
argv = yargs
.command({
command: '*',
handler: function () {
console.log('use the html command to walk');
console.log('walker html -p ./public -d 4');
}
})
// html command
.command({
command: 'html',
describe: 'walk for html',
handler: function (argv) {
// walk with path, and depth
klaw(argv.path, {
depthLimit: argv.depth
})
.on('data', function (item) {
if (path.extname(item.path).toLowerCase() === '.html') {
console.log(item.path);
}
});
}
})
// options to set path, and depth
.option('depth', {alias: 'd',default:'0'})
.option('path', {alias: 'p',default:'./'})
.argv;

2.3 - nopt

One of the first option parsers I have worked with is nopt this is a good choice if you are looking for a more minimal solution for just option parsing, and not much of anything else.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
parsed = nopt(
// options
{
"write" : Number,
"text" : String,
"filename" : String,
"path" : path
},
// shorthands
{
"w" : "--write",
"t" : "--text",
"f" : "--filename",
"p" : "--path"
},
process.argv,
2
);