将命令行参数发送到 npm 脚本

IT技术 javascript node.js npm
2021-01-18 19:20:07

scriptspackage.json目前部分看起来像这样:

"scripts": {
    "start": "node ./script.js server"
}

...这意味着我可以运行npm start以启动服务器。到现在为止还挺好。

但是,我希望能够运行类似的东西npm start 8080并将参数传递给script.js(例如npm start 8080=> node ./script.js server 8080)。这可能吗?

6个回答

npm 2 及更新版本

自 npm 2 (2014) 以来,可以将 args 传递给npm run语法如下:

npm run <command> [-- <args>]

请注意--分隔符,用于分隔传递给npm命令本身的参数和传递给脚本的参数。

举个例子package.json

  "scripts": {
    "grunt": "grunt",
    "server": "node server.js"
  }

以下是将参数传递给这些脚本的方法:

npm run grunt -- task:target  // invokes `grunt task:target`
npm run server -- --port=1337 // invokes `node server.js --port=1337`

注意如果您的参数不以-or开头--,则--不需要显式分隔符;但为了清楚起见,最好还是这样做。

npm run grunt task:target     // invokes `grunt task:target`

请注意下面的行为差异(test.jshas console.log(process.argv)):以-开头的参数-- 传递给npm而不是传递给脚本,并在那里默默地吞下。

$ npm run test foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js',  'foobar']

$ npm run test -foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']

$ npm run test --foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']

$ npm run test -- foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', 'foobar']

$ npm run test -- -foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '-foobar']

$ npm run test -- --foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '--foobar']

当您使用npm 实际使用的参数时,差异更加明显

$ npm test --help      // this is disguised `npm --help test`
npm test [-- <args>]

aliases: tst, t

要获取参数值,请参阅此问题为了读取命名参数,最好使用像yargsminimist这样的解析库nodejsprocess.argv全局公开,包含命令行参数值,但这是一个低级 API(以空格分隔的字符串数组,由操作系统提供给节点可执行文件)。


编辑 2013.10.03:目前无法直接使用。但是有一个相关的GitHub 问题已打开npm以实现您要求的行为。似乎共识是实现这一点,但这取决于之前解决的另一个问题。


原始答案(2013.01):作为某种解决方法(虽然不是很方便),您可以执行以下操作:

说你的包名来自package.jsonmyPackage,你也有

"scripts": {
    "start": "node ./script.js server"
}

然后加入package.json

"config": {
    "myPort": "8080"
}

而在你的script.js

// defaulting to 8080 in case if script invoked not via "npm run-script" but directly
var port = process.env.npm_package_config_myPort || 8080

这样,默认情况下npm start将使用 8080。但是您可以配置它(该值将存储npm在其内部存储中):

npm config set myPackage:myPort 9090

然后,在调用时npm start,将使用 9090(默认值 frompackage.json被覆盖)。

这也可以与像这样的包完美配合yargs之后的所有参数--都可以在您的脚本中完美解析。
2021-03-10 19:20:07
@Spock 您可以使用 shell 函数。这是一个 eslint+tslint 设置,我用来允许将自定义参数传递给 eslint,例如,通过 "npm run lint -- -f unix": "lint": "f() { eslint -f codeframe $@ . && npm run tslint && echo 'lint clean!'; }; f"
2021-03-15 19:20:07
AFAIKS,这只能在脚本的末尾添加参数。如果中间需要参数怎么办?
2021-03-22 19:20:07
设置“myPackage:myPort 9090”值的更好方法是在命令“--myPackage:myPort=9090”中使用配置标志 - keithcirkel.co.uk/how-to-use-npm-as-a-build -工具
2021-03-25 19:20:07
-- --args 天哪,这很奇怪,但还好
2021-03-30 19:20:07

您要求能够运行类似 npm start 8080. 这是可能的,而无需修改script.js或配置文件,如下所示。

例如,在您的"scripts"JSON 值中,包括--

"start": "node ./script.js server $PORT"

然后从命令行:

$ PORT=8080 npm start

我已经确认这使用 bash 和 npm 1.4.23 有效。请注意,此变通方法不需要解决 GitHub npm问题 #3494

这真的很好用。你也可以做一些事情,比如node ./script.js server ${PORT:-8080}让它成为可选的。
2021-03-10 19:20:07
嘿@graup 这对我NODE_PORT=${PORT=8080}有用(注意相等)但不是 :- 语法
2021-03-17 19:20:07
这不适用于跨平台!例如,在 Windows 上,命令需要是node ./script.js server %PORT%. 考虑使用cross-varcross-env
2021-04-02 19:20:07
我似乎无法在 Windows 中使用 git bash 执行此操作。有人让它工作吗?(相同的命令适用于 ubuntu)
2021-04-05 19:20:07
@JeungminOh ARG1=1 ARG2=2 ARGx=x npm start
2021-04-05 19:20:07

你也可以这样做:

package.json

"scripts": {
    "cool": "./cool.js"
}

cool.js

 console.log({ myVar: process.env.npm_config_myVar });

在 CLI 中:

npm --myVar=something run-script cool

应该输出:

{ myVar: 'something' }

更新:使用 npm 3.10.3,它似乎将process.env.npm_config_变量小写我也在使用better-npm-run,所以我不确定这是否是普通的默认行为,但这个答案有效的。而不是process.env.npm_config_myVar,尝试process.env.npm_config_myvar

这是错误的。process.env.npm_config_myVar返回 true,而不是值。
2021-03-16 19:20:07
谢谢这对我有用!我特别缺少您在命令行中指定的变量名称的“npm_config_”前缀。
2021-03-22 19:20:07
适用于 npm 6.8.0 版,但仅当我使用小写作为变量名时。它看起来像 npm 将其更改为小写
2021-03-27 19:20:07
@K-ToxicityinSO正在增长。如果您忘记添加=到参数,就是这种情况例如:npm --myVar something ...将返回true。但是这个:npm --myVar=something ...将返回值本身。
2021-03-27 19:20:07
很好的解决方案,适用于 npm 6.5.0 上的小写参数
2021-04-09 19:20:07

jakub.g的答案是正确的,但是使用 grunt 的示例似乎有点复杂。

所以我更简单的答案:

- 向 npm 脚本发送命令行参数

将命令行参数发送到 npm 脚本的语法:

npm run [command] [-- <args>]

想象一下,我们在 package.json 中有一个 npm start 任务来启动 webpack 开发服务器:

"scripts": {
  "start": "webpack-dev-server --port 5000"
},

我们从命令行运行它 npm start

现在,如果我们想将端口传递给 npm 脚本:

"scripts": {
  "start": "webpack-dev-server --port process.env.port || 8080"
},

运行它并通过命令行传递端口(例如 5000)将如下所示:

npm start --port:5000

- 使用 package.json 配置:

正如jakub.g所提到的,您也可以在package.json的配置中设置参数

"config": {
  "myPort": "5000"
}

"scripts": {
  "start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080"
},

npm start 将使用您的配置中指定的端口,或者您可以覆盖它

npm config set myPackage:myPort 3000

- 在你的 npm 脚本中设置一个参数

读取 npm 脚本中设置的变量的示例。在这个例子中NODE_ENV

"scripts": {
  "start:prod": "NODE_ENV=prod node server.js",
  "start:dev": "NODE_ENV=dev node server.js"
},

在阅读NODE_ENV server.js无论是督促开发

var env = process.env.NODE_ENV || 'prod'

if(env === 'dev'){
    var app = require("./serverDev.js");
} else {
    var app = require("./serverProd.js");
}
请注意,除非您使用跨环境,否则"start:prod": "NODE_ENV=prod node server.js"in这样的语法package.json在 Windows 上不起作用
2021-03-13 19:20:07
更正?: "start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080" },应该"start": "webpack-dev-server --port $npm_package_config_myPort || 8080" },按照我的使用教程来解释进程 ref 显然可以在 javascript 中使用。
2021-03-13 19:20:07

npm 2.x 开始,您可以通过将 args--

终端

npm run-script start -- --foo=3

包.json

"start": "node ./index.js"

索引.js

console.log('process.argv', process.argv);
@KyleMit:您可能是对的,尽管目前答案是多余的,即使当时可能有所不同。除了我的第一条评论,我将删除所有内容。
2021-04-05 19:20:07