3141

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:

$ node server.js folder 

here server.js is my server code. Node.js help says this is possible:

$ node -h Usage: node [options] script.js [arguments] 

How would I access those arguments in JavaScript? Somehow I was not able to find this information on the web.

2
  • It's probably a good idea to manage your configuration in a centralized manner using something like nconf github.com/flatiron/nconf It helps you work with configuration files, environment variables, command-line arguments. Commented May 26, 2012 at 0:10
  • And here's configvention, my own, minimal, readonly interface for nconf. Commented Jan 26, 2014 at 12:02

42 Answers 42

1
2
4

You can get command-line information from process.argv()

And I don't want to limit the problem to node.js. Instead, I want to turn it into how to parse the string as the argument.

console.log(ArgumentParser(`--debug --msg="Hello World" --title="Test" --desc=demo -open --level=5 --MyFloat=3.14`)) 

output

{ "debug": true, "msg": "Hello World", "title": "Test", "desc": "demo", "open": true, "level": 5, "MyFloat": 3.14 } 

code

Pure javascript, no dependencies needed

// 👇 Below is Test (() => { window.onload = () => { const testArray = [ `--debug --msg="Hello World" --title="Test" --desc=demo -open --level=5 --MyFloat=3.14`, ] for (const testData of testArray) { try { const obj = ArgumentParser(testData) console.log(obj) } catch (e) { console.error(e.message) } } } })() // 👇 Script class ParserError extends Error { } function Cursor(str, pos) { this.str = str this.pos = pos this.MoveRight = (step = 1) => { this.pos += step } this.MoveToNextPara = () => { const curStr = this.str.substring(this.pos) const match = /^(?<all> *--?(?<name>[a-zA-Z_][a-zA-Z0-9_]*)(=(?<value>[^-]*))?)/g.exec(curStr) // https://regex101.com/r/k004Gv/2 if (match) { let {groups: {all, name, value}} = match if (value !== undefined) { value = value.trim() if (value.slice(0, 1) === '"') { // string if (value.slice(-1) !== '"') { throw new ParserError(`Parsing error: '"' expected`) } value = value.slice(1, -1) } else { // number or string (without '"') value = isNaN(Number(value)) ? String(value) : Number(value) } } this.MoveRight(all.length) return [name, value ?? true] // If the value is undefined, then set it as ture. } throw new ParserError(`illegal format detected. ${curStr}`) } } function ArgumentParser(str) { const obj = {} const cursor = new Cursor(str, 0) while (1) { const [name, value] = cursor.MoveToNextPara() obj[name] = value if (cursor.pos === str.length) { return obj } } }

Sign up to request clarification or add additional context in comments.

Comments

4

NodeJS exposes a global variable called process.

we can use:

process.argv 

to get the command line arguments passes to our script.

The output of process.argv will be a list in the following order:

[ full-path-to-node-executable, full-path-to-the-script-file ...additonal-arguments-we-provide ] 

Comments

3

process.argv is your friend, capturing command line args is natively supported in Node JS. See example below::

process.argv.forEach((val, index) => { console.log(`${index}: ${val}`); }) 

Comments

3

I extended the getArgs function just to get also commands, as well as flags (-f, --anotherflag) and named args (--data=blablabla):

  1. The module
/** * @module getArgs.js * get command line arguments (commands, named arguments, flags) * * @see https://stackoverflow.com/a/54098693/1786393 * * @return {Object} * */ function getArgs () { const commands = [] 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 }) } else { // commands commands.push(arg) } }) return { args, commands } } // test if (require.main === module) { // node getArgs test --dir=examples/getUserName --start=getUserName.askName console.log( getArgs() ) } module.exports = { getArgs } 
  1. Usage example:
$ node lib/getArgs test --dir=examples/getUserName --start=getUserName.askName { args: { dir: 'examples/getUserName', start: 'getUserName.askName' }, commands: [ 'test' ] } $ node lib/getArgs --dir=examples/getUserName --start=getUserName.askName test tutorial { args: { dir: 'examples/getUserName', start: 'getUserName.askName' }, commands: [ 'test', 'tutorial' ] } 

Comments

3

Use the minimist npm package. it is the easiest method and don't need to worry about anything.

const arguments = require("minimist")(process.argv.slice(2)); // get the extra argument of command line . eg node app.js --process="sendEmailWithReminder" 

We can use it in windows task scheduler too.

enter image description here

enter image description here

enter image description here

Comments

3

Simplest possible solution to precisely what the OP asked

if (process.argv.length != 3) { console.log("Please call with a folder name") process.exit(1) } let arg = process.argv[2] console.log("your folder is:", arg) 

and hence

% node test.js Please call with a folder name % node test.js catPhotos your folder is: catPhotos 

That's it.

Comments

2

The original question was asking to pass command line arguments, not about more complex parsing of arguments. Yet with all the complex answers, they all missed one simple, useful variation.

Did you know that the Unix shell supports named arguments? This dates back to the original Bourne shell in the 1980s. Usage is simple:

$ FOO=one BAR=two nodejs myscript.js 

To fetch the parameters in Javascript:

var foo = process.env.FOO; var bar = process.env.BAR; 

Named parameters are much easier to read, once you get past two or three parameters. Optional parameters are simple, and order is not fixed.

(This might even work on Windows, with the recent support for Unix shells.)

Also, shockingly few Unix programmers know of this usage. :)

6 Comments

These aren't "named parameters" as such, they are environment variables.
They are parameters, and they are named. That they are environment variables is incidental. Or perhaps you have some other definition? :)
A named parameter would be --myvalue=abc. Environment variables have entirely different semantics such as being passed to all child processes as well (which is a problem both ways - you may have something passed that you didn't expect, and you may forward something you didn't intend) and not being passed across WSL interop boundaries unless separately specified in WSLENV. Those different semantics are why they have environment in the name.
Once more, then I am dropping this thread. We are passing named parameters to a program. Yes, the semantics are slightly different, but only that. Ever read the library code that calls "C" main()? Both command line and environment are just pointers to character buffers. For the most/many (small) tools that I write, the slightly more global nature of parameters passed in the environment is of no practical concern. For larger works I construct the environment for child processes. (Good practice to limit risks.) At this point I assume we will not agree.
Plus, while you do seem to be aware of the differences in behavior and how to avoid problems with them, the people learning about this from your post for the first time won't be. You advertise environment variables as named command line arguments, implying they would behave as one would expect from command line arguments without warning that they don't, and you never refer to them even once in your post by their actual googleable name. So you are just laying out traps for novice programmers who will be stumped why using a "named argument" PATH breaks in multiple mysterious ways for instance.
|
1

as stated in the node docs The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched.

For example, assuming the following script for process-args.js:

// print process.argv process.argv.forEach((val, index) => { console.log(`${index}: ${val}`); }); 

Launching the Node.js process as:

 $ node process-args.js one two=three four 

Would generate the output:

0: /usr/local/bin/node 1: /Users/mjr/work/node/process-args.js 2: one 3: two=three 4: four 

Comments

1

Most of the people have given good answers. I would also like to contribute something here. I am providing the answer using lodash library to iterate through all command line arguments we pass while starting the app:

// Lodash library const _ = require('lodash'); // Function that goes through each CommandLine Arguments and prints it to the console. const runApp = () => { _.map(process.argv, (arg) => { console.log(arg); }); }; // Calling the function. runApp(); 

To run above code just run following commands:

npm install node index.js xyz abc 123 456 

The result will be:

xyz abc 123 456 

Comments

0

Typescript way to do it with minimist.

npm i minimist @types/minimist

app.ts

// import import { MyProgram } from './main'; // libraries import minimist from 'minimist'; // interfaces import { ParsedArgs } from 'minimist'; // code const args: ParsedArgs = minimist(process.argv.slice(2)); let app = new MyProgram(args.a).getApp(); export { app }; 

Command to run after compiling to JavaScript with gulp

node app.js -a MyParam

2 Comments

The answer to the user's question is process.argv.slice(2). What benefit does the rest of your answer add? What value does minimist provide over process.argv?
@jpaugh this is the TypeScript way to do it, if you want interfaces and intellisense to help you in VS Code
-1

You can use Rest operator to accept n numbers of arguments in a function and use it like this i have posted a sample program i hope which will help you to get the point.

 function sum(...theArgs) { let total = 0; for (const arg of theArgs) { total += arg; } return total; } console.log(sum(1, 2, 3)); // Expected output: 6 console.log(sum(1, 2, 3, 4)); // Expected output: 10 enter code here 

1 Comment

just to clarify the downvote (wasn't me) the question is about CLI (command line interface) arguments and not function arguments
-3

A simple snippet if any need it:

var fs = require('fs'), objMod = {}; process.argv.slice(2).map(function(y, i) { y = y.split('='); if (y[0] && y[1]) objMod[y[0]] = y[1]; else console.log('Error in argument number ' + (i+1)); }); 

1 Comment

Why do you use require('fs')?
1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.