将命令行参数传递给 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 --",
...
},
...
要克服没有内置功能将参数传递到脚本中间的限制,请考虑以下解决方案:
对于 Bash 唯一的解决方案,请参阅 “解决方案 1” 部分。
如果需要跨平台支持,请遵循“解决方案 2” 部分中描述的解决方案。
解决方案 1 - Bash(MacOS/Linux/ 等..):
在 package.json 的 scripts
部分配置您的 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 函数执行以下操作:
- 首先 运行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
注:
在这种情况下,尾随 dv
部分是将传递给您的 vumper
脚本的参数。
必须在参数前指定特殊选项--
。 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
我的 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 --",
...
},
...
要克服没有内置功能将参数传递到脚本中间的限制,请考虑以下解决方案:
对于 Bash 唯一的解决方案,请参阅 “解决方案 1” 部分。
如果需要跨平台支持,请遵循“解决方案 2” 部分中描述的解决方案。
解决方案 1 - Bash(MacOS/Linux/ 等..):
在 package.json 的 scripts
部分配置您的 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 函数执行以下操作:
- 首先 运行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
注:
在这种情况下,尾随
dv
部分是将传递给您的vumper
脚本的参数。必须在参数前指定特殊选项
--
。 docs 将--
选项描述为:... The special option
--
is used bygetopt
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 afternpm 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