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

arn*_*art 691 javascript node.js npm

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

"scripts": {
    "start": "node ./script.js server"
}
Run Code Online (Sandbox Code Playgroud)

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

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

jak*_*b.g 947

编辑2014.10.30: 可以将args传递给npm runnpm 2.0.0

语法如下:

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

请注意必要的--.需要将传递给npm命令本身的params和传递给脚本的params分开.

所以,如果你有 package.json

"scripts": {
    "grunt": "grunt",
    "server": "node server.js"
}
Run Code Online (Sandbox Code Playgroud)

然后以下命令是等效的:

grunt task:target => npm run grunt -- task:target

node server.js --port=1337 => npm run server -- --port=1337

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


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


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

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

"scripts": {
    "start": "node ./script.js server"
}
Run Code Online (Sandbox Code Playgroud)

然后加入package.json:

"config": {
    "myPort": "8080"
}
Run Code Online (Sandbox Code Playgroud)

在你的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
Run Code Online (Sandbox Code Playgroud)

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

npm config set myPackage:myPort 9090
Run Code Online (Sandbox Code Playgroud)

然后,在调用时npm start,将使用9090(默认来自package.json被覆盖).

  • ` - --args`神圣的废话,这很奇怪,但没关系 (78认同)
  • AFAIKS,这只能将参数添加到脚本的末尾.如果你需要中间的参数怎么办? (8认同)
  • @Spock您可以使用shell函数.这是一个eslint + tslint设置,我用它来允许将自定义args传递给eslint,用于insance,通过"npm run lint - -f unix":"lint":"f(){eslint -f codeframe $ @.&& npm run tslint && echo'lint clean!';}; f" (8认同)
  • 设置“ myPackage:myPort 9090”值的更好方法是使用命令“ --myPackage:myPort = 9090”的配置标志-https://www.keithcirkel.co.uk/how-to-use-npm作为构建工具/ (2认同)

cje*_*nek 201

你问到能够运行什么 npm start 8080.这可以在不需要script.js如下修改或配置文件的情况下实现.

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

"start": "node ./script.js server $PORT"
Run Code Online (Sandbox Code Playgroud)

然后从命令行:

$ PORT=8080 npm start
Run Code Online (Sandbox Code Playgroud)

我已经确认这可以使用bash和npm 1.4.23.请注意,这种解决方法不需要解决GitHub npm 问题#3494.

  • 这非常有效.您还可以执行类似`node ./script.js server $ {PORT:-8080}`的操作,使其成为可选项. (11认同)
  • 这不适用于跨平台!例如,在Windows上,命令需要是`node ./script.js server%PORT%`.考虑使用[cross-var](https://www.npmjs.com/package/cross-var)和[cross-env](https://www.npmjs.com/package/cross-env). (11认同)
  • 我似乎无法在使用git bash的windows中执行此操作.有人得到它的工作吗?(相同的命令适用于ubuntu) (6认同)
  • 嘿@graup 这对我有用`NODE_PORT=${PORT=8080}`(注意相等)但不是 :- 语法 (4认同)
  • @JeungminOh `ARG1=1 ARG2=2 ARGx=x npm start` (4认同)

fra*_*srv 84

你也可以这样做:

package.json:

"scripts": {
    "cool": "./cool.js"
}
Run Code Online (Sandbox Code Playgroud)

cool.js:

 console.log({ myVar: process.env.npm_config_myVar });
Run Code Online (Sandbox Code Playgroud)

在CLI中:

npm --myVar=something run-script cool
Run Code Online (Sandbox Code Playgroud)

应输出:

{ myVar: 'something' }
Run Code Online (Sandbox Code Playgroud)

更新:使用npm 3.10.3,它似乎降低了process.env.npm_config_变量的范围?我也在使用better-npm-run,所以我不确定这是否是香草的默认行为,但这个答案有效的.而不是process.env.npm_config_myVar,尝试process.env.npm_config_myvar

  • 谢谢这对我有用!我特别想念您在命令行中指定的变量名称的"npm_config_"前缀. (4认同)
  • 这是错的.`process.env.npm_config_myVar`返回true,而不是值. (2认同)

svn*_*vnm 70

jakub.g的回答是正确的,但是使用grunt的例子看起来有点复杂.

所以我的答案更简单:

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

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

npm run [command] [-- <args>]
Run Code Online (Sandbox Code Playgroud)

想象一下,我们的package.json中有一个npm启动任务,以启动webpack dev服务器:

"scripts": {
  "start": "webpack-dev-server --port 5000"
},
Run Code Online (Sandbox Code Playgroud)

我们从命令行运行它 npm start

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

"scripts": {
  "start": "webpack-dev-server --port process.env.port || 8080"
},
Run Code Online (Sandbox Code Playgroud)

运行这个并通过命令行传递端口例如5000将如下:

npm start --port:5000
Run Code Online (Sandbox Code Playgroud)

- 使用package.json配置:

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

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

"scripts": {
  "start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080"
},
Run Code Online (Sandbox Code Playgroud)

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

npm config set myPackage:myPort 3000
Run Code Online (Sandbox Code Playgroud)

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

读取npm脚本中的变量集的示例.在这个例子中NODE_ENV

"scripts": {
  "start:prod": "NODE_ENV=prod node server.js",
  "start:dev": "NODE_ENV=dev node server.js"
},
Run Code Online (Sandbox Code Playgroud)

在阅读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");
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`package.json`中的``start:prod":"NODE_ENV = prod node server.js"`这样的语法在Windows上不起作用,除非你使用[cross-env](https://www.npmjs的.com /包/交叉ENV) (5认同)
  • 更正吗? ”,根据[本教程](http://www.marcusoft.net/2015/08/npm-scripting-configs-and-arguments.html#npm-configuration)的说明使用。显然,可以在javascript中使用process ref。 (2认同)

And*_*dri 43

我过去一直在使用这种单线,在离开 Node.js 一段时间后,最近不得不尝试重新发现它。与@francoisrv 提到的解决方案类似,它利用了node_config_*变量。

创建以下最小package.json文件:

{
  "name": "argument",
  "version": "1.0.0",
  "scripts": {
    "argument": "echo \"The value of --foo is '${npm_config_foo}'\""
  }
}
Run Code Online (Sandbox Code Playgroud)

运行以下命令:

npm run argument --foo=bar
Run Code Online (Sandbox Code Playgroud)

观察以下输出:

--foo 的值是 'bar'

所有这些都很好地记录在 npm 官方文档中:

注:环境变量标题解释说,里面的脚本变量也表现不同,以什么文档中定义。当涉及到区分大小写以及参数是用空格还是等号定义时,情况确实如此。

注意:如果您使用带连字符的参数,这些将在相应的环境变量中替换为下划线。例如,npm run example --foo-bar=baz将对应于${npm_config_foo_bar}

注意:对于非 WSL Windows 用户,请参阅下面@Doctor Blue 的评论... TL;DR 替换${npm_config_foo}%npm_config_foo%.

  • 我想到了。只需使用“%npm_config_foo%”即可。纯 Windows 命令行/powershell 在这里。(也没有选择。) (3认同)
  • 你好。我正在尝试使用您的示例,但恐怕它对我不起作用。我复制粘贴了您的“参数”脚本,并对要运行的命令执行了相同的操作(`npm run argument --foo=bar`),但变量没有被替换:“”--foo 的值是 ' ${npm_config_foo}'"`。如果重要的话,可以在 Windows 10 上运行,使用 NPM 版本 6.9.0。 (2认同)

Pet*_*ter 32

process.argv在代码中使用然后只提供$*脚本值条目的尾随.

作为一个例子,尝试使用一个简单的脚本,它只是将提供的参数记录到标准输出echoargs.js:

console.log('arguments: ' + process.argv.slice(2));
Run Code Online (Sandbox Code Playgroud)

的package.json:

"scripts": {
    "start": "node echoargs.js $*"
}
Run Code Online (Sandbox Code Playgroud)

例子:

> npm start 1 2 3
arguments: 1,2,3
Run Code Online (Sandbox Code Playgroud)

process.argv[0]是可执行文件(node),process.argv[1]是你的脚本.

使用npm v5.3.0和node v8.4.0进行测试


mxt*_*xt3 32

对于 Windows 上的 PowerShell 用户

接受的答案对我来说不适用于 npm 6.14。添加 no--或包含一次都不起作用。然而,在参数之前放置--两次或一次就可以了。"--"例子:

npm run <my_script> -- -- <my arguments like --this>
Run Code Online (Sandbox Code Playgroud)

怀疑原因

就像在 bash 中一样,--指示 PowerShell 将所有以下参数视为文字字符串,而不是选项(例如,请参阅此答案)。问题似乎是该命令的解释次数比预期多一倍,从而丢失了'--'. 例如,通过做

npm run <my_script> -- --option value
Run Code Online (Sandbox Code Playgroud)

npm 将运行

<my_script> value
Run Code Online (Sandbox Code Playgroud)

然而,做

<my_script> value
Run Code Online (Sandbox Code Playgroud)

结果是

npm run <my_script> "--" --option value
Run Code Online (Sandbox Code Playgroud)

效果很好。

  • 另一种方法是使用“---”三斜杠 (5认同)

Gre*_*ier 31

npm 2.x支持 cli args

命令

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

的package.json

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

Index.js

console.log('process.argv', process.argv);


Dan*_*oss 19

如果你想将参数传递给npm脚本的中间,而不是将它们附加到末尾,那么内联环境变量似乎很好地工作:

"scripts": {
  "dev": "BABEL_ARGS=-w npm run build && cd lib/server && nodemon index.js",
  "start": "npm run build && node lib/server/index.js",
  "build": "mkdir -p lib && babel $BABEL_ARGS -s inline --stage 0 src -d lib",
},
Run Code Online (Sandbox Code Playgroud)

在这里,npm run dev-wwatch标志传递给babel,但npm run start只运行一次常规构建.

  • 需要使用[cross-env](http://stackoverflow.com/a/37356976/878514)在Windows上使用它. (2认同)

Ale*_*hev 14

上面的大多数答案只是将参数传递到由 npm 调用的 NodeJS 脚本中。我的解决方案是通用的。

只需使用 shell 解释器(例如sh)调用包装 npm 脚本并像往常一样传递参数。唯一的例外是第一个参数编号是0

例如,您想添加 npm script someprogram --env=<argument_1>,其中someprogram只打印env参数的值:

包.json

"scripts": {
  "command": "sh -c 'someprogram --env=$0'"
}
Run Code Online (Sandbox Code Playgroud)

当你运行它时:

"scripts": {
  "command": "sh -c 'someprogram --env=$0'"
}
Run Code Online (Sandbox Code Playgroud)


Mad*_*oop 7

--使用脚本将参数分开并添加所有必需的参数,我们稍后可以通过索引访问它们。

npm run start -- myemail@gmail.com 100
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方式获取节点中的参数

const params = process.argv.slice(2);
console.log(params);
Run Code Online (Sandbox Code Playgroud)

输出

['myemail@gmail.com', '100']
Run Code Online (Sandbox Code Playgroud)


小智 6

这并不能真正回答您的问题,但您可以始终使用环境变量:

"scripts": {
    "start": "PORT=3000 node server.js"
}
Run Code Online (Sandbox Code Playgroud)

然后在您的server.js文件中:

var port = process.env.PORT || 3000;
Run Code Online (Sandbox Code Playgroud)

  • 只要您在 Unix 平台上,这就很好。不幸的是,它不适用于 Windows,因为它有自己的约定。 (3认同)