Pass command line args to npm scripts in package.json

删除回忆录丶 提交于 2019-11-27 14:28:22

Short Answer:

Essentially, what you're wanting is to have an npm-script something like this, whereby <arg-here> is provide via the CLI;

...
"scripts": {
  "my-build": "npm run vumper <arg-here> && npm run format",
  ...
},
...

However, unfortunately npm does not have a built-in feature to achieve this.

The special npm option --, (refer to the end of Solution 1 below for further info about this option), can only be used to pass an argument to the END of a script but NOT into the MIDDLE. So, if your two commands were in the opposite order, the -- option could be used like this:

...
"scripts": {
  "my-build": "npm run format && npm run vumper --",
  ...
},
...

To overcome the limitation of there being no built-in feature to pass an argument into the MIDDLE of a script consider the following solutions:

  1. For a Bash only solution refer to the "Solution 1" section.

  2. If cross platform support is required then follow the solution described in the "Solution 2" section.


Solution 1 - Bash (MacOS/Linux/ etc..):

Configure your my-build script in the scripts section of package.json to invoke a Bash shell function, as shown below:

package.json

...
"scripts": {
  "my-build": "func() { npm run vumper \"$1\" && npm run format; }; func",
  "vumper": "node node_modules/vumper/index.js",
  "format": "prettier --single-quote -width=80 --write package.json"
},
...

Explanation:

The Bash function named func does the following:

  1. Firstly runs npm run vumper <arg>. Whereby <arg> will be the shell argument passed via the CLI. It is referenced in the script using $1 (i.e. the first positional parameter/argument).
  2. Subsequently it runs the script named format via the command npm run format.

These two npm run commands are chained using the && operator, so the second npm run format command will only run if the initial npm run vumper <arg> command completes successfully (i.e. returns a 0 exit code).

Running my-build script:

To invoke my-build via your CLI you'll need to run:

npm run my-build -- dv

Note:

  1. In this instance the trailing dv part is the argument that will be passed to your vumper script.

  2. The special option -- must be specified before the argument. The docs describe the -- option as:

    ... 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.


Solution 2 - Cross-platform:

For a cross-platform solution, (one which works successfully with Bash, Windows Command Prompt / cmd.exe, and PowerShell etc..), you'll need to utilize a nodejs helper script as follows.

run.js

Let's name the nodejs script run.js and save it in the projects root directory, at the same level as package.json.

const execSync = require('child_process').execSync;

const arg = process.argv[2] || 'dv'; // Default value `dv` if no args provided via CLI.

execSync('npm run vumper ' + arg, {stdio:[0, 1, 2]});
execSync('npm run format', {stdio:[0, 1, 2]});

package.json

Configure your my-build script to invoke run.js as follows:

...
"scripts": {
  "my-build": "node run",
  "vumper": "node node_modules/vumper/index.js",
  "format": "prettier --single-quote -width=80 --write package.json"
},
...

Running my-build script:

As per Solution 1, to invoke my-build via your CLI you'll need to run:

npm run my-build -- dv

Explanation:

  • run.js utilizes process.argv to obtain the argument passed via the CLI (e.g. dv). If no argument is provided when running npm run my-build the default value, (i.e. dv), is passed to the vumper npm-script.

  • run.js also utilizes child_process.execSync(...) to shell-out/invoke the two npm run commands.

Sanish Joseph

I think you can use concurrently.

https://www.npmjs.com/package/concurrently

You have to install concurrently first then use it as follows,

Multiple commands can be run with arguments is supported

So in your case, it will be

concurrently "npm:vumber dv" "npm:format"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!