发送命令行参数到npm脚本

我的package.json scripts部分目前看起来像这样:

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

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

不过,我希望能够运行像npm start 8080这样的东西,并将parameter passing给script.js (例如npm start 8080 => node ./script.js server 8080 )。 这可能吗?

编辑2014.10.30: 可以将parameter passing给npm 2.0.0以后的npm

语法如下:

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

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

所以如果你有package.json

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

那么相当于

grunt task:target

通过npm运行将是

npm run grunt -- task:target

和相当于

node server.js --port=1337

将会

npm run server -- --port=1337


编辑2013.10.03:目前不可能直接。 但是在npm上有一个相关的GitHub问题来实现你所要求的行为。 似乎共识就是要实现这个,但是这取决于以前解决的另一个问题。


原来的答案:作为一种解决方法(虽然不是很方便),你可以做如下:

说你package.json的包名是myPackage ,你也有

 "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.但是,您可以对其进行configuration(该值将通过npm存储在其内部存储器中):

 npm config set myPackage:myPort 9090 

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

你问能够运行 npm start 8080这样的东西。 这是可能的,无需修改script.js或configuration文件如下。

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

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

然后从命令行:

 $ PORT=8080 npm start 

我已经证实,这个工程使用bash和npm 1.4.23。 请注意,此解决方法不需要解决GitHub npm 问题#3494 。

你也可以这样做:

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_variables? 我也使用better-npm-run ,所以我不知道这是否是香草默认的行为,但这个答案正在工作。 而不是process.env.npm_config_myVar ,请尝试process.env.npm_config_myvar

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

所以我更简单的回答:

– 将命令行参数发送给npm脚本

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

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

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

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

我们使用npm start从命令行npm start

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

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

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

 npm start --port:5000 

– 使用package.jsonconfiguration:

正如jakub.g提到的,你可以在package.json的configuration文件中设置参数

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

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

 npm config set myPackage:myPort 3000 

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

阅读你的npm脚本中设置的variables的一个例子。 在这个例子中NODE_ENV

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

读取server.js中的 NODE_ENV proddev

 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 args

命令

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

的package.json

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

Index.js

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

如果要将parameter passing给npm脚本的中间,而不是只将它们追加到最后,那么内联环境variables似乎很好地工作:

 "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 watch标志传递给babel,但npm run start只运行一次常规构build。

这不能真正回答你的问题,但你总是可以使用环境variables:

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

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

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

从我所看到的,当人们想要以更简单的方式运行脚本时,人们使用package.json脚本。 例如,要使用安装在本地node_modules中的nodemon,我们不能直接从cli调用nodemon ,但可以使用./node_modules/nodemon/nodemon.js来调用它。 所以,为了简化这种长时间打字,我们可以把这个…


     ...

    脚本:{
       'start':'nodemon app.js'
     }

     ...

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

我想说的是,如果你只是想用node命令启动你的服务器,我不认为你需要使用scripts 。 键入npm startnode app.js具有相同的努力。

但是,如果您确实想要使用nodemon ,并且想要传递dynamic参数,则不要使用script 。 尝试使用符号链接。

例如使用迁移与sequelize 。 我创build一个符号链接…

ln -s node_modules/sequelize/bin/sequelize sequelize

…当我打电话时,我可以通过任何争论…

 ./sequlize -h /* show help */ ./sequelize -m /* upgrade migration */ ./sequelize -m -u /* downgrade migration */ 

等等…

在这一点上,使用符号链接是我能find的最好的方法,但是我并不认为这是最好的做法。

我也希望你的意见,我的答案。

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

echoargs.js:

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

的package.json:

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

例子:

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

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

使用npm v5.3.0和v8.4.0节点进行testing