I have a web server written in Node.js and I would like to launch with a specific folder. I\'m not sure how to access arguments in JavaScript. I\'m running node like this:
function getArgs () {
const args = {};
process.argv
.slice(2, process.argv.length)
.forEach( arg => {
// long arg
if (arg.slice(0,2) === '--') {
const longArg = arg.split('=');
const longArgFlag = longArg[0].slice(2,longArg[0].length);
const longArgValue = longArg.length > 1 ? longArg[1] : true;
args[longArgFlag] = longArgValue;
}
// flags
else if (arg[0] === '-') {
const flags = arg.slice(1,arg.length).split('');
flags.forEach(flag => {
args[flag] = true;
});
}
});
return args;
}
const args = getArgs();
console.log(args);
input
node test.js -D --name=Hello
output
{ D: true, name: 'Hello' }
input
node config/build.js -lHRs --ip=$HOST --port=$PORT --env=dev
output
{
l: true,
H: true,
R: true,
s: true,
ip: '127.0.0.1',
port: '8080',
env: 'dev'
}
Passing arguments is easy, and receiving them is just a matter of reading the process.argv array Node makes accessible from everywhere, basically. But you're sure to want to read them as key/value pairs, so you'll need a piece to script to interpret it.
Joseph Merdrignac posted a beautiful one using reduce, but it relied on a key=value
syntax instead of -k value
and --key value
. I rewrote it much uglier and longer to use that second standard, and I'll post it as an answer because it wouldn't fit as a commentary. But it does get the job done.
const args = process.argv.slice(2).reduce((acc,arg,cur,arr)=>{
if(arg.match(/^--/)){
acc[arg.substring(2)] = true
acc['_lastkey'] = arg.substring(2)
} else
if(arg.match(/^-[^-]/)){
for(key of arg.substring(1).split('')){
acc[key] = true
acc['_lastkey'] = key
}
} else
if(acc['_lastkey']){
acc[acc['_lastkey']] = arg
delete acc['_lastkey']
} else
acc[arg] = true
if(cur==arr.length-1)
delete acc['_lastkey']
return acc
},{})
With this code a command node script.js alpha beta -charlie delta --echo foxtrot
would give you the following object
args = {
"alpha":true,
"beta":true,
"c":true,
"h":true,
"a":true,
"r":true
"l":true,
"i":true,
"e":"delta",
"echo":"foxtrot"
}
The arguments are stored in process.argv
Here are the node docs on handling command line args:
process.argv
is an array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments.
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
This will generate:
$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four
const args = process.argv;
console.log(args);
This returns:
$ node server.js one two=three four
['node', '/home/server.js', 'one', 'two=three', 'four']
Official docs
Minimist: For minimal argument parsing.
Commander.js: Most adopted module for argument parsing.
Meow: Lighter alternative to Commander.js
Yargs: More sophisticated argument parsing (heavy).
Vorpal.js: Mature / interactive command-line applications with argument parsing.
Here's my 0-dep solution for named arguments:
const args = process.argv
.slice(2)
.map(arg => arg.split('='))
.reduce((args, [value, key]) => {
args[value] = key;
return args;
}, {});
console.log(args.foo)
console.log(args.fizz)
Example:
$ node test.js foo=bar fizz=buzz
bar
buzz
Note: Naturally this will fail when the argument contains a =
. This is only for very simple usage.
You can reach command line arguments using system.args
. And i use the solution below to parse arguments into an object, so i can get which one i want by name.
var system = require('system');
var args = {};
system.args.map(function(x){return x.split("=")})
.map(function(y){args[y[0]]=y[1]});
now you don't need to know the index of the argument. use it like args.whatever
Note: you should use named arguments like
file.js x=1 y=2
to use this solution.