DEV Community

loading...
Cover image for Creating a command-line app in Node.js: Argument Parsing

Creating a command-line app in Node.js: Argument Parsing

kumar_abhirup profile image Kumar Abhirup Updated on ・3 min read

This article is in the continuity of part 1. So before you proceed, please make sure you have followed the steps in part 1. :)

In Part 1, we learned about how a Node App can be run like it is a CLI. In this post, we will learn about Argument parsing in command-line app.

What is argument parsing in a CLI?

If you have ever used CLIs like git and yarn, you know you have to pass a --flag as a suffix to the CLI command.

For eg. npm install. Here, install is an argument passed to the npm command that tells Node Package Manager to install a package.

In the same way, your CLI might need a different set of predefined arguments (also called 'parameters') to work properly. It is often used for doing different tasks and features in a CLI.

Argument parsing in Node.js

  • Create a file named index.js...

  • In the file, paste the below code.

console.log(process.argv)
  • Now, in the terminal, run the following command to get the given output.
$ node index.js wow this is an argument

# Output 👇

[ 'node',
  '/home/username/Desktop/index.js',
  'wow',
  'this',
  'is',
  'an',
  'argument' ]

Now, you can use the output you get to detect what argument is passed and you can make your CLI behave accordingly.

Better Argument Parsing

process.argv is the very fundamental line of code to know what argument is being passed.

In a CLI, you'll have to make users use a combination of commands to do certain things. For eg. npm install -g bulk-mail-cli. Here, install is passed as an argument and -g (--global) as a flag.

Computing what all the combinations will do in a CLI can be a hefty task. Therefore, it is recommended that you use tried and tested libraries for argument parsing and its detection.

Libraries to parse arguments and flags.

Commander

Let us see how Commander works. In Part 1, we created a demo CLI project. Continue coding in the index.js of the same coding project.

The tutorial below will be relevant only if you have read Part 1 of the series.

Define the module.

const commander = require('commander')

To use it in your program, paste the following code...

commander
    .version('v0.0.1')
    .description('This is a dummy demo CLI.')
    .option('-n, --name <type>', 'To input a name')
    .option('demo', 'To output demo')
    .parse(process.argv)

The above lines of code will now help you parse and read the --version, -n, --name, demo arguments.

Reading the arguments

To read the argument, you now have to simply do the following...

// Runs only if `name` argument is passed with a `<type>`...
if (commander.name) console.log(`Your name is ${commander.name}.`)

// Runs only if `demo` argument is passed...
if (commander.demo) console.log(`This is a DEMO.`)

Try it out!

If you have continued from Part 1, then you have a package.json already created. cd in the directory where your code is stored and run the following in the terminal...

$ thisDemoCli demo
This is a DEMO.

$ thisDemoCli --name "Kumar Abhirup"
Your name is Kumar Abhirup.

$ thisDemoCli --version
v0.0.1

Hooray! Now you are successfully parsing the arguments and doing something with it!

I hope this article helps you understand the fundamentals of how a Command-Line app works in Node.js.


About me

I am Kumar Abhirup, a 16-year-old JavaScript React developer from India who keeps learning a new thing every single day.

Connect with me on Twitter 🐦
My personal website and portfolio 🖥️

Comment below your better ways, and suggestions to improve this article. :)

Discussion

pic
Editor guide
Collapse
elaspog profile image
László Pogány

Hi Kumar,

I'm sorry to tell you, but your tutorial is not a quality work...

  • the description you have written it's simply not enough to a nodejs beginner to recreate the same application you wrote

  • does not precisely determines where to put this new code if someone would like to continue your previous example

  • simply doesn't work if I don't change the 'command' string to 'commander' in the next lines:

instead of:
if (command.name) console.log(Your name is ${command.name}.)
if (command.demo) console.log(This is a DEMO.)

this is correct:
if (commander.name) console.log(Your name is ${commander.name}.)
if (commander.demo) console.log(This is a DEMO.)

  • even if I change, I get a strange behavior when I try to run the demo option:

$ node index.js demo
Your name is function(str) {
if (arguments.length === 0) return this._name;
this._name = str;
return this;
}.
This is a DEMO.

  • the '-v' option is not recognized by this library, the capital '-V' is the good one:

$ node index.js -v
error: unknown option '-v'

$ node index.js -V
v0.0.1

  • there is no git repository behind your code, where people could check your working solution if they don't succeed

Please be more precise when you are publishing any tutorial in the future, because you can cause a lot of headache to the beginners.

Collapse
kumar_abhirup profile image
Kumar Abhirup Author

Hey! Thank you so much! This means so much to me!

I will be taking care that I don't make over-assumptions about what people know and don't know.

Thank you again!

Also, if possible, can you please give me this critical feedback on my other posts as well? This will help me improve!

Will update the article this weekend.

Collapse
elaspog profile image
László Pogány

I can write feedback later of course, but my most important suggestions in every case would be:

  • Everything need to be reproducible and verifiable by others

    • This is why the professionals use git where they put their code/configuration/settings etc. and attach the URL for the example before/after the article
  • If you write tutorials for beginners (I can assume this by the topic choice), everything should be written in step-by-step manner (where to put exactly what, what to uncommet, or where to cut from, what are the main steps, main stages and snapshots of the code for a given step/functionality etc.)

  • What are the requirements/environment/dependencies (that's OK in your case because npm makes this easy), how to install or set them. The dependencies/URLs might break by time, they always should be checked whether they are still valid.

Thread Thread
kumar_abhirup profile image
Kumar Abhirup Author

Thanks, will look forward to implementing these from next tutorials I create! Will also update the last ones.

Collapse
elaspog profile image
László Pogány

UPDATE:

  • while experimenting with this library I've found out, that "name" is not a good choice as name of the parameter, because there is an inner private function (_name) used by this library which gives back the script name.

console.dir(commander)
// ..
_args: [],
_name: 'index',
_optionValues: {},
//...

If you call this function it gives back the filename

console.log(commander.name());
// index

That's the reason why this happens if you run the script from console with "demo" parameter:

$ node index.js demo
Your name is function(str) {
if (arguments.length === 0) return this._name;
this._name = str;
return this;
}.
This is a DEMO.