首页 文章

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

提问于
浏览
456

package.jsonscripts 部分目前看起来像这样:

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

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

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

10 回答

  • 154

    在代码中使用 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和node v8.4.0进行测试

  • 65

    Edit 2014.10.30: It's possible to pass args to npm run as of npm 2.0.0

    语法如下:

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

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

    所以如果你有 package.json

    "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

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


    编辑2013.10.03:目前无法直接使用 . 但是在npm上打开了一个相关的GitHub问题来实现你要求的行为 . 似乎共识是实现这一点,但它取决于之前解决的另一个问题 .


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

    假设 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.但是您可以配置它(该值将由 npm 存储在其内部存储中):

    npm config set myPackage:myPort 9090
    

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

  • 12

    你要求能够运行像 npm start 8080 这样的东西 . 这可以在不需要如下修改 script.js 或配置文件的情况下实现 .

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

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

    然后从命令行:

    $ PORT=8080 npm start
    

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

  • 18

    你也可以这样做:

    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 ,所以我不确定这是否是vanilla默认行为,但这个答案是有效的 . 而不是 process.env.npm_config_myVar ,请尝试 process.env.npm_config_myvar

  • 5

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

    所以我更简单的回答:

    - Sending a command line argument to an npm script

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

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

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

    "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
    

    - Using package.json config:

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

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

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

    npm config set myPackage:myPort 3000
    

    - Setting a param in your npm script

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

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

    读取server.js中的NODE_ENV prod或dev

    var env = process.env.NODE_ENV || 'prod'
    
    if(env === 'dev'){
        var app = require("./serverDev.js");
    } else {
        var app = require("./serverProd.js");
    }
    
  • 662

    npm 2.x support cli args

    命令

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

    的package.json

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

    Index.js

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

  • 47

    如果你想将参数传递给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",
    },
    

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

  • 24

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

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

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

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

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

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

    ...然后调用 npm start 使用'nodemon',它将app.js作为第一个参数 .

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

    但是如果你确实想使用 nodemon ,并希望传递动态参数,也不要使用 script . 尝试使用符号链接 .

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

    ln -s node_modules/sequelize/bin/sequelize sequelize

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

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

    等等...

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

    我也希望你的意见得到我的回答 .

  • 3

    当我试图通过运行sequelize seed来解决我的问题时,我发现了这个问题:生成cli命令:

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

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

    经过一些实验后得出答案 . 这是我在 package.json 的命令

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

    ...这里是在终端中运行它以生成 user 的种子文件的示例

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

    FYI

    yarn -v
    1.6.0
    
    npm -v
    5.6.0
    

相关问题