Enviando argumentos da linha de comando para o script npm

A parte dos scripts do meu package.json atualmente se parece com isso:

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

… o que significa que posso executar o npm start para iniciar o servidor. Por enquanto, tudo bem.

No entanto, eu gostaria de poder executar algo como o npm start 8080 e ter o (s) argumento (s) passado (s) para o script.js (por exemplo, npm start 8080 => node ./script.js server 8080 ). Isso é possível?

   

Edit 2014.10.30: É possível passar args para npm run partir do npm 2.0.0

A syntax é a seguinte:

npm run [-- ]

Observe o necessário -- . É necessário separar os parâmetros transmitidos ao comando npm e os parâmetros transmitidos ao seu script.

Então, se você tiver em package.json

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

Então os seguintes comandos seriam equivalentes:

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

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

Para obter o valor do parâmetro, veja esta questão . Para ler parâmetros nomeados, provavelmente é melhor usar uma biblioteca de análise como yargs ou minimist ; nodejs expõe process.argv globalmente, contendo valores de parâmetro de linha de comando, mas essa é uma API de baixo nível (matriz de strings separadas por espaços em branco, conforme fornecida pelo sistema operacional para o executável do nó).


Editar 2013.10.03: Não é possível no momento diretamente. Mas há um problema relacionado ao GitHub aberto no npm para implementar o comportamento que você está pedindo. Parece que o consenso é que isso seja implementado, mas isso depende de outro problema que está sendo resolvido antes.


Resposta original: Como algum tipo de solução alternativa (embora não muito útil), você pode fazer o seguinte:

Diga o nome do seu pacote de package.json é myPackage e você também

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

Em seguida, adicione o package.json :

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

E no seu 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 

Dessa forma, por padrão, o npm start usará o 8080. Você pode, no entanto, configurá-lo (o valor será armazenado pelo npm em seu armazenamento interno):

 npm config set myPackage:myPort 9090 

Então, quando invocar o npm start , 9090 será usado (o padrão de package.json é substituído).

Você pediu para ser capaz de executar algo como o npm start 8080 . Isso é possível sem a necessidade de modificar o script.js ou os arquivos de configuração da seguinte maneira.

Por exemplo, no seu valor JSON "scripts" , include–

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

E então a partir da linha de comando:

 $ PORT=8080 npm start 

Eu confirmei que isso funciona usando bash e npm 1.4.23. Note que esta solução alternativa não requer que o GitHub npm # 3494 seja resolvido.

Você também pode fazer isso:

Em package.json :

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

Em cool.js :

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

Na CLI:

 npm --myVar=something run-script cool 

Deve saída:

 { myVar: 'something' } 

Update: Usando o npm 3.10.3, parece que ele reduz as variables process.env.npm_config_ ? Eu também estou usando better-npm-run , então eu não tenho certeza se este é um comportamento padrão ou não, mas esta resposta está funcionando. Em vez de process.env.npm_config_myVar , tente process.env.npm_config_myvar

A resposta de jakub.g está correta, mas um exemplo usando grunhido parece um pouco complexo.

Então minha resposta mais simples:

– Enviando um argumento de linha de comando para um script npm

Sintaxe para enviar argumentos da linha de comando para um script npm:

 npm run [command] [-- ] 

Imagine que tenhamos uma tarefa de boot npm em nosso pacote.json para iniciar o servidor de desenvolvimento webpack:

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

Nós executamos isso a partir da linha de comando com o npm start

Agora, se quisermos passar uma porta para o script npm:

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

executar isso e passar a porta, por exemplo, 5000 via linha de comando seria o seguinte:

 npm start --port:5000 

– Usando o pacote.json config:

Como mencionado por jakub.g , você pode alternativamente definir parâmetros na configuração do seu pacote.json

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

npm start usará a porta especificada na sua configuração ou, alternativamente, você poderá substituí-la

 npm config set myPackage:myPort 3000 

– Configurando um param no seu script npm

Um exemplo de leitura de uma variável definida no seu script npm. Neste exemplo NODE_ENV

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

leia NODE_ENV em server.js ou prod ou dev

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

npm 2.x support cli args

Comando

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

Package.json

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

Index.js

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

Use process.argv em seu código e, em seguida, apenas forneça um $* à sua input de valor de scripts.

echoargs.js:

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

package.json:

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

Exemplos:

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

process.argv[0] é o executável (nó), process.argv[1] é o seu script.

Testado com o npm v5.3.0 e o nó v8.4.0

Se você quiser passar argumentos para o meio de um script npm, em vez de apenas anexá-los ao final, as variables ​​de ambiente inline parecem funcionar bem:

 "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", }, 

Aqui, npm run dev passa o flag -w watch para babel, mas npm run start apenas executa uma build regular uma vez.

Isso realmente não responde à sua pergunta, mas você pode sempre usar variables ​​de ambiente:

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

Então, no seu arquivo server.js:

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

Pelo que vejo, as pessoas usam scripts package.json quando gostariam de executar o script de maneira mais simples. Por exemplo, para usar o nodemon que foi instalado no node_modules local, não podemos chamar o nodemon diretamente do cli, mas podemos chamá-lo usando ./node_modules/nodemon/nodemon.js . Então, para simplificar essa longa digitação, podemos colocar isso …


     ...

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

     ...

… então chame npm start para usar o ‘nodemon’ que tem o app.js como o primeiro argumento.

O que estou tentando dizer, se você quiser apenas iniciar seu servidor com o comando node , não creio que precise usar scripts . Digitar npm start ou node app.js tem o mesmo esforço.

Mas se você quiser usar o nodemon e quiser passar um argumento dynamic, também não use script . Tente usar o symlink.

Por exemplo, usando a migration com sequelize . Eu crio um symlink …

ln -s node_modules/sequelize/bin/sequelize sequelize

… E eu posso passar qualquer argumento quando eu chamo de …

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

etc …

Neste ponto, usar o symlink é a melhor maneira que eu poderia descobrir, mas não acho que seja a melhor prática.

Eu também espero a sua opinião para a minha resposta.

Eu encontrei esta questão enquanto eu estava tentando resolver o meu problema com a execução de semente sequelize: comando generate cli:

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

Deixe-me chegar ao ponto. Eu queria ter um comando de script curto no meu arquivo package.json e fornecer o argumento –name ao mesmo tempo

A resposta veio depois de algumas experiências. Aqui está o meu comando em package.json

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

… e aqui está e exemplo de executá-lo no terminal para gerar um arquivo de semente para um usuário

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

Para sua informação

 yarn -v 1.6.0 npm -v 5.6.0