关于javascript:向NPM脚本发送命令行参数

Sending command line arguments to npm script

scriptsportion我package.json目前就像这样: </P >

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

...which均值,我可以运行npm start到启动的服务器。那么远那么好。 </P >

但是,我很喜欢的是能运行的某样npm start 8080和有"argument(S)通过对script.js(如npm start 8080=> node ./script.js server 8080)。这是可能的吗? </P >


编辑2014.10.30:从NPM 2.0.0开始,可以将args传递给npm run

语法如下:

npm run [-- ]

注意必要的--。需要将传递给npm命令本身的参数和传递给脚本的参数分开。

所以如果你有在江户城的话

1
2
3
4
"scripts": {
   "grunt":"grunt",
   "server":"node server.js"
}

则以下命令等效:

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

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

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

edit 2013.10.03:目前无法直接进行。但在npm上有一个相关的github问题,用于实现您所要求的行为。似乎共识是要落实这一点,但这取决于之前正在解决的另一个问题。

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

你说你从package.json寄来的包裹名是myPackage,你也有

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

然后加入package.json

1
2
3
"config": {
   "myPort":"8080"
}

在你的以东书1〔14〕中:

1
2
// 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存储在其内部存储器中):

1
npm config set myPackage:myPort 9090

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


你要求能够运行类似于npm start 8080的程序。这是可能的,不需要修改script.js或如下配置文件。

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

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

然后从命令行:

1
$ PORT=8080 npm start

我已经确认这是使用bash和npm 1.4.23实现的。请注意,此解决方案不需要解决Github NPM问题3494。


你也可以这样做:

package.json中:

1
2
3
"scripts": {
   "cool":"./cool.js"
}

cool.js中:

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

在CLI:

1
npm --myVar=something run-script cool

应输出:

1
{ myVar: 'something' }

更新:使用NPM 3.10.3,它似乎降低了process.env.npm_config_变量?我也在使用better-npm-run,所以我不确定这是否是普通的默认行为,但是这个答案是有效的。用process.env.npm_config_myVar代替process.env.npm_config_myVar


Jakub.g的答案是正确的,但是使用Grunt的例子似乎有点复杂。

所以我的简单答案是:

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

向NPM脚本发送命令行参数的语法:

1
npm run [command] [-- ]

假设我们在package.json中有一个NPM启动任务来启动webpack dev服务器:

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

我们用npm start从命令行运行

现在,如果要将端口传递给NPM脚本:

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

运行此命令并通过端口(例如5000)如下:

1
npm start --port:5000

-使用package.json配置:

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

1
2
3
4
5
6
7
"config": {
 "myPort":"5000"
}

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

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

1
npm config set myPackage:myPort 3000

-在NPM脚本中设置参数

读取NPM脚本中变量集的示例。在本例中,NODE_ENV

1
2
3
4
"scripts": {
 "start:prod":"NODE_ENV=prod node server.js",
 "start:dev":"NODE_ENV=dev node server.js"
},

读取server.js中的node_env prod或dev

1
2
3
4
5
6
7
var env = process.env.NODE_ENV || 'prod'

if(env === 'dev'){
    var app = require("./serverDev.js");
} else {
    var app = require("./serverProd.js");
}


npm 2.x支持cli参数

命令

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

包装袋

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

索引文件

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


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

举个例子,用一个简单的脚本来尝试一下,该脚本只将提供的参数记录到标准输出echoargs.js中:

1
console.log('arguments: ' + process.argv.slice(2));

包装:JSON:

1
2
3
"scripts": {
   "start":"node echoargs.js $*"
}

实例:

1
2
> npm start 1 2 3
arguments: 1,2,3

process.argv[0]是可执行文件(节点),process.argv[1]是脚本。

使用NPM v5.3.0和节点v8.4.0进行测试


如果您希望将参数传递到NPM脚本的中间,而不是将它们附加到末尾,那么内联环境变量似乎可以很好地工作:

1
2
3
4
5
"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",
},

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


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

1
2
3
"scripts": {
   "start":"PORT=3000 node server.js"
}

然后在server.js文件中:

1
var port = process.env.PORT || 3000;


在我看来,当人们希望以更简单的方式运行脚本时,他们使用package.json脚本。例如,要使用安装在本地节点模块中的nodemon,我们不能直接从cli调用nodemon,但可以使用./node_modules/nodemon/nodemon.js调用它。所以,为了简化这段长时间的输入,我们可以把它…

1
2
3
4
5
6
7
    ...

    scripts: {
      'start': 'nodemon app.js'
    }

    ...

…然后调用npm start使用以app.js为第一个参数的'nodemon'。

我想说的是,如果您只想用node命令启动服务器,我认为您不需要使用scripts。键入npm startnode app.js也有同样的效果。

但是如果你想使用nodemon,并且想传递一个动态参数,也不要使用script。尝试使用symlink。

例如,使用sequelize进行迁移。我创建一个符号链接…

ln -s node_modules/sequelize/bin/sequelize sequelize

…当我称之为…

1
2
3
4
5
./sequlize -h /* show help */

./sequelize -m /* upgrade migration */

./sequelize -m -u /* downgrade migration */

等。。。

在这一点上,使用symlink是我能理解的最好方法,但我并不认为这是最佳实践。

我也希望你对我的回答有意见。


npm run script_target--基本上,这是传递命令行参数的方法,但只有当脚本只有一个命令运行时,它才能工作,就像我正在运行一个命令一样,即npm run start--4200

1
2
3
"script":{
      "start" :"ng serve --port="
 }

这将运行以传递命令行参数,但如果我们一起运行多个命令,如npm run build c:/workspace/file,该怎么办?

1
2
3
"script":{
      "build" :"copy c:/file  && ng build"
 }

但在运行copy c:/file&ng build c:/work space/file时,它会像这样解释我们期望这样的事情发生复制c:/file c:/work space/file&ng build

注意:-所以在脚本中只有一个命令的情况下,命令行参数只起作用。

我读了上面的一些答案,其中一些是写的,您可以使用$symbol访问命令行参数,但这不起作用。


我在尝试解决运行sequelize seed:generate cli命令时发现了这个问题:

1
node_modules/.bin/sequelize seed:generate --name=user

让我讲讲重点。我希望在package.json文件中有一个简短的脚本命令,同时提供--name参数

答案是在一些实验之后得出的。这是package.json中的命令

1
2
3
"scripts: {
 "
seed:generate":"NODE_ENV=development node_modules/.bin/sequelize seed:generate"
}

…下面是在终端中运行它为用户生成种子文件的示例

1
2
3
> yarn seed:generate --name=user

> npm run seed:generate -- --name=user

供参考

1
2
3
4
5
yarn -v
1.6.0

npm -v
5.6.0