将命令行参数传递给package.json中的npm脚本 [英] Pass command line args to npm scripts in package.json

查看:283
本文介绍了将命令行参数传递给package.json中的npm脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的package.json中包含以下脚本:

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

'vumper'软件包采用命令行参数(例如'dv').我想做的是有一个连续运行这两个命令的命令.

基本上,我希望能够运行:

npm run vumber dv

然后

npm run format

但是在一个命令中,类似于

npm run my-build dv

可以运行上述两个命令,正确接受命令行参数'dv'并将其传递给第一个npm run vumper.这可能吗?

解决方案

简短答案:

本质上,您想要的是具有这样的npm脚本,从而通过CLI提供<arg-here>

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

但是,不幸的是,npm没有内置功能来实现此目的.

特殊的npm选项--(有关此选项的更多信息,请参阅下面的解决方案1 ​​的末尾),只能用于将参数传递给 END 的脚本,但不在中间.因此,如果两个命令的顺序相反,则可以像这样使用--选项:

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

要克服没有内置功能将参数传递到脚本中间的局限性,请考虑以下解决方案:

  1. 有关仅限Bash的解决方案,请参见解决方案1" 部分.

  2. 如果需要跨平台支持,请遵循解决方案2" 部分中所述的解决方案.


解决方案1- Bash(MacOS/Linux/等.):

package.json scripts部分中配置my-build脚本,以调用Bash ... "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" }, ...

说明:

名为func的Bash函数执行以下操作:

  1. 首先运行npm run vumper <arg>.其中,<arg>是通过CLI传递的shell参数.在脚本中使用$1进行引用(即第一个 positional参数/参数).
  2. 随后,它通过命令npm run format运行名为format的脚本.

这两个npm run命令是使用&&运算符链接在一起的,因此,第二个npm run format命令将仅在初始npm run vumper <arg>命令成功完成(即返回0退出代码)时运行. >

运行my-build脚本:

要通过您的CLI调用my-build,您需要运行:

 npm run my-build -- dv
 

注意:

  1. 在这种情况下,结尾的dv部分是将传递给您的vumper脚本的参数.

  2. 必须在参数前指定特殊选项--. 文档--选项描述为:

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

    配置您的my-build脚本以如下方式调用 run.js :

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

    运行my-build脚本:

    根据解决方案1 ​​,要通过CLI调用my-build,您需要运行:

     npm run my-build -- dv
     

    说明:

    I have the below scripts in my package.json:

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

    The 'vumper' package takes in a command line argument (such as 'dv'). What I would like to be able to do is have a command that runs both of these in succession.

    Essentially, I would like to be able to run:

    npm run vumber dv
    

    and then

    npm run format
    

    but in one command, something like

    npm run my-build dv
    

    which would run both of the above commands, correctly accepting the command line argument 'dv' and passing it to the first npm run vumper. Is this possible?

    解决方案

    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.

    这篇关于将命令行参数传递给package.json中的npm脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆