If you want to keep the npm run command that you enter via the CLI the same as per your question. (i.e. avoid adding yet another npm special option (--) to it, as per @MikePatrick 's answer).
Change your npm-scripts to the following instead:
"scripts": {
"exec:dev": "export NODE_ENV=development && npm run exec --",
"exec:stage": "export NODE_ENV=stage && npm run exec --",
"exec:prod": "export NODE_ENV=production && npm run exec --",
"exec": "node myapp.js"
}
Note: the npm special option (--) added to the end of the first three scripts.
Demo
For demonstration purposes, lets say myapp.js is as follows:
myapp.js
const args = (process.argv.slice(2));
const nodeEnv = process.env.NODE_ENV;
console.log(nodeEnv);
console.log(args);
Testing:
Running npm run exec:dev -- -a 123 -b 456 prints:
development
[ '-a', '123', '-b', '456' ]
Running npm run exec:stage -- -a 123 -b 456 prints:
stage
[ '-a', '123', '-b', '456' ]
Running npm run exec:prod -- -a 123 -b 456 prints:
production
[ '-a', '123', '-b', '456' ]
Further info
The docs for npm-run-script describe the npm special option (--) as follows:
... The special option -- is used by getopt to delimit the end of the options. npm will pass all the arguments after the -- directly to your script ... The arguments will only be passed to the script specified after npm run and not to any pre or post script.