将命令行参数传递给 package.json 中的 npm 脚本

Pass command line args to npm scripts in package.json

我的 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 运行 vumper。这可能吗?

简答:

本质上,您想要的是一个像这样的 npm 脚本,其中 <arg-here> 是通过 CLI 提供的;

...
"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.jsonscripts 部分配置您的 my-build 脚本以调用 Bash shell function ,如下图:

package.json

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

解释:

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

  1. 首先 运行s npm run vumper <arg>。其中 <arg> 将是通过 CLI 传递的 shell 参数。它在脚本中使用 </code> 引用(即第一个 <a href="https://www.gnu.org/software/bash/manual/html_node/Positional-Parameters.html" rel="noreferrer">positional parameter</a>/参数)。</li> <li>随后它 运行 通过命令 <code>npm run format 创建名为 format 的脚本。

这两个 npm run 命令使用 && 运算符链接起来,因此如果初始 npm run vumper <arg> 命令完成,第二个 npm run format 命令只会 运行成功(即 returns 一个 0 退出代码)。

运行 my-build 脚本:

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

npm run my-build -- dv

注:

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

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

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


解决方案 2 - 跨平台:

对于跨平台解决方案,(一个与 Bash、Windows 命令提示符/cmd.exe 和 PowerShell 等一起成功运行的解决方案),您需要如下使用 nodejs 帮助程序脚本。

run.js

我们把nodejs脚本命名为run.js,保存在项目根目录下,与package.json[同级] =152=].

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

解释:

  • run.js 利用 process.argv 获取通过 CLI 传递的参数(例如 dv)。如果在 运行 宁 npm run my-build 时没有提供参数,默认值(即 dv)被传递给 vumper npm-script。

  • run.js也利用child_process.execSync(...)shell-out /调用两个 npm run 命令。

Npm 现在 一个 built-in 选项可以将 cli 参数直接传递给脚本。 cli 参数存储在前缀为 npm_config_<flagname> 的环境变量中,它们需要非常严格的语法,格式为 --<flagname>=<flagvalue>.

示例:

 "my-build": "npm run vumper %npm_config_myflag% && npm run format",

在终端中,运行 npm run my-build --myflag=my_value执行npm run vumper my_value && npm run format.

注:

要在 npm 脚本中引用环境变量,您必须使用特定于平台的语法,即 Windows 中的 %npm_config_myflag% 或 Linux 中的 $npm_config_myflag

更新:

为了避免与用于配置 npm 本身的 npm_config 变量发生冲突 的风险,只需 为您的参数添加一个唯一的前缀,例如您的应用名称。

潜在冲突是一个非常普遍的问题,适用于许多情况:任何应用程序都可以使用其他应用程序已经使用的环境变量;因此,环境变量通常以应用程序名称为前缀(例如 NVM_HOME、JAVA_HOME)。但是这种潜在的冲突并不是避免使用环境变量的好理由。我认为这同样适用于 npm params / npm_config env vars。 The doc 没有说明冲突的风险,暗示我想它们应该照常管理。

我的首选方法是使用环境变量:

{
  "scripts": {
    "ncc-build": "ncc build $ACTION/src/index.ts -o $ACTION/dist",
    "build:pr-changelog": "ACTION=pr-changelog npm run ncc-build",
  }
}

它应该在 UNIX 系统中工作。不过,我不确定 windows 平台兼容性。

一种不同的方法 - 深入了解您的依赖链:

npm 脚本部分:

"test:local": "cross-env-shell UPDATE_BASELINE=false UPDATE_MODULE=%npm_config_vizdifsingle% run-p koa:ci wdio:local",
"test:remote": "cross-env-shell UPDATE_BASELINE=false  UPDATE_MODULE=%npm_config_vizdifsingle% run-p localtunnel:start koa:ci wdio:remote"

通过使用 crossenv 和 npm 的值放置,您可以将 args 传递给 env.args

像这样:

npm run test:local --vizdifsingle=some,value,or,values

您可以在

process.env.npm_config_update_module