17

I have a simple node.js backend script and I want to capture command line arguments along with the keys/values from a config.json file and environment variables. The second two I am having no problem with, but I am having nearly inexplicable trouble capturing the command line args.

I can capture the command line arguments this way:

var nconf = require('nconf');
nconf.argv().env().file({file: './config.json'});

var csvFilePath = nconf.argv().get()._[0]; // var csvFilePath = process.argv[2];
var csvType = nconf.argv().get()._[1];     // var csvType = process.argv[3];

these two calls are equivalent to process.argv[index], except the index is changed.

There has to be a more straightforward way to capture the command line arguments but even when I debug and look through the variables that nconf yields, I still can't figure it out.

Anyone with nconf experience care to help?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817

3 Answers3

10

I believe the best way to do this is like so:

//contents of app.js
var nconf = require('nconf').argv();

if you call your program with the follow command line command:

node app.js --one foo --two bar

then in your program you can access these command line args like so:

var nconf = require('nconf').argv();
var one = nconf.get('one');  //one = 'foo'
var two = nconf.get('two');  //two = 'bar'

so you need the -- symbol in front of the identifier, then you can access the command line args.

Frankly, as a message to the nconf module author Charlie Robbins, I think it would better to not mix everything into one big hash.

It would be better if you did this instead:

var foo = nconf.argv.get('one');
var node_env = nconf.env.get('NODE_ENV');

I think it is more intuitive and less error prone.

Also, for those starting node with 'npm start':

to my knowledge you need two extra hyphens like so:

npm start -- --one foo --two bar

with the extra hyphens/dashes you let Bash know that the args are for your node.js executable, not for the NPM node.js executable

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 1
    On your comments at the end there: I could be wrong, but I think not having them in one big hash kind of defeats the purpose of having `nconf`. The whole point is that you can have a hierarchy along the lines of "argv overrides environment variable which overrides defaults" or whatever you want. If you keep them all separate like that and manage the overrides manually, then there's not really any point in using something like `nconf`. That's the value it adds. You don't have to check a, then check b, then check c. Just check nconf. – Trott May 07 '15 at 01:44
  • 1
    you could still provide overrides and defaults for argv and env, just do this nconf.overrides({argv:{},env:{}}); and nconf.defaults({argv:{},env:{}});it's not that hard. – Alexander Mills May 07 '15 at 17:05
  • 1
    Providing separate argv-specific and env-specific defaults defeats the whole purpose of using nconf. If you have no reason to have nconf merge all your configuration elements into a single configuration object, I would recommend using something like `minimist` for argv rather than using `nconf`. – Trott May 07 '15 at 19:01
  • hi with `npm start -- --one foo` it's not working, do you have any idea how to do it with `npm start`, thank you – Sabrina Luo May 06 '16 at 08:21
  • sabrina is there an error message, can you log the properties in process.argv? – Alexander Mills May 06 '16 at 17:33
  • `npm start -- --one foo` just saved my life. Nothing about it in the docs! Awesome extra bit of info! – hyprstack Feb 20 '19 at 09:01
7

Slightly shorter/cleaner:

var nconf = require('nconf');
nconf.argv().env().file({file: './config.json'});

var csvFilePath = nconf.get('_')[0]; // var csvFilePath = process.argv[2];
var csvType = nconf.get('_')[1];     // var csvType = process.argv[3];

If you name your parameter (say, --foo=bar or -f bar), then you can use .get('foo') or .get('f') rather than using the array index.

Trott
  • 66,479
  • 23
  • 173
  • 212
  • thanks for this Trott- can you speak to what .get('_') is doing? What is the lo-dash for? – Alexander Mills Jun 30 '15 at 07:39
  • `nconf` uses `optimist` which uses `_` for an array of non-hyphenated options. In other words, it's the arguments to the command. See https://github.com/substack/node-optimist#and-non-hypenated-options-too-just-use-argv_ for an example. – Trott Jun 30 '15 at 19:55
2

Try this

npm start -- --one foo --two bar

Its working for me in windows

Umanath
  • 81
  • 6