Invio di argomenti dalla riga di comando allo script npm

La porzione degli scripts del mio package.json momento assomiglia a questo:

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

… il che significa che posso avviare npm start per avviare il server. Fin qui tutto bene.

Tuttavia, mi piacerebbe essere in grado di eseguire qualcosa come npm start 8080 e avere gli argomenti passati a script.js (es. npm start 8080 => node ./script.js server 8080 ). È ansible?

Modifica 2014.10.30: È ansible passare argomenti a npm run partire da npm 2.0.0

La syntax è la seguente:

npm run [-- ]

Nota il necessario -- . È necessario separare i parametri passati al comando npm stesso e i parametri passati al tuo script.

Quindi se hai in package.json

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

Quindi i seguenti comandi sarebbero equivalenti:

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

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

Per ottenere il valore del parametro, vedere questa domanda . Per leggere parametri con nome, è probabilmente meglio usare una libreria di analisi come yargs o minimist ; nodejs espone globalmente process.argv , contenente i valori dei parametri della riga di comando, ma questa è un’API di basso livello (array di stringhe separati da spazi bianchi, come fornito dal sistema operativo all’eseguibile del nodo).


Modifica 2013.10.03: non è attualmente ansible direttamente. Ma c’è un problema relativo a GitHub aperto su npm per implementare il comportamento che stai richiedendo. Sembra che il consenso sia implementato, ma dipende da un altro problema risolto in precedenza.


Risposta originale: come soluzione alternativa (sebbene non molto utile), puoi procedere come segue:

Dì il nome del tuo pacchetto da package.json è myPackage e lo hai anche tu

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

Quindi aggiungere in package.json :

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

E nel tuo 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 

In questo modo, per impostazione predefinita, npm start utilizzerà 8080. È tuttavia ansible configurarlo (il valore verrà archiviato da npm nella sua memoria interna):

 npm config set myPackage:myPort 9090 

Quindi, quando si richiama npm start , verrà utilizzato 9090 (il valore predefinito da package.json viene ignorato).

Hai chiesto di essere in grado di eseguire qualcosa come npm start 8080 . Questo è ansible senza la necessità di modificare script.js o file di configurazione come segue.

Ad esempio, nel valore JSON "scripts" , include–

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

E poi dalla riga di comando:

 $ PORT=8080 npm start 

Ho confermato che funziona con bash e npm 1.4.23. Nota che questo work-around non richiede il problema n. 3494 di GitHub npm per essere risolto.

Potresti anche farlo:

In package.json :

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

In cool.js :

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

Nella CLI:

 npm --myVar=something run-script cool 

Dovrebbe uscita:

 { myVar: 'something' } 

Aggiornamento: utilizzando npm 3.10.3, sembra che minacci le variabili process.env.npm_config_ ? Sto anche utilizzando better-npm-run , quindi non sono sicuro se questo è il comportamento predefinito di vaniglia o meno, ma questa risposta funziona. Invece di process.env.npm_config_myVar , prova process.env.npm_config_myvar

La risposta di jakub.g è corretta, tuttavia un esempio di grunt sembra un po ‘complesso.

Quindi la mia risposta più semplice:

– Invio di un argomento da riga di comando a uno script npm

Sintassi per l’invio di argomenti da riga di comando a uno script npm:

 npm run [command] [-- ] 

Immagina di avere un task di avvio di npm nel nostro package.json per avviare il server di sviluppo webpack:

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

Eseguiamo questo dalla riga di comando con npm start

Ora se vogliamo passare una porta allo script npm:

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

eseguendo questo e passando la porta ad esempio 5000 tramite la riga di comando sarebbe come segue:

 npm start --port:5000 

– Usando la configurazione di package.json:

Come menzionato da jakub.g , puoi in alternativa impostare i parametri nella configurazione del tuo pacchetto.json

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

npm start userà la porta specificata nella tua configurazione, o in alternativa puoi sovrascriverla

 npm config set myPackage:myPort 3000 

– Impostazione di un parametro nel tuo script npm

Un esempio di lettura di una variabile impostata nello script npm. In questo esempio NODE_ENV

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

leggi NODE_ENV in server.js o prod o 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 supporto cli args

Comando

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

Package.json

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

Index.js

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

Utilizza process.argv nel codice quindi fornisci un valore $* alla voce del valore degli script.

echoargs.js:

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

package.json:

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

Esempi:

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

process.argv[0] è l’eseguibile (nodo), process.argv[1] è il tuo script.

Testato con npm v5.3.0 e node v8.4.0

Se si desidera passare argomenti al centro di uno script npm, anziché limitarsi ad aggiungerli alla fine, le variabili di ambiente inline sembrano funzionare correttamente:

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

Qui, npm run dev passa la flag -w watch a babel, ma npm run start esegue solo una build regolare una volta.

Questo in realtà non risponde alla tua domanda, ma puoi sempre utilizzare le variabili di ambiente:

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

Quindi nel tuo file server.js:

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

Da quello che vedo, le persone usano gli script package.json quando vorrebbero eseguire script in modo più semplice. Ad esempio, per usare nodemon installato nei node_modules locali, non possiamo chiamare nodemon direttamente dal cli, ma possiamo chiamarlo usando ./node_modules/nodemon/nodemon.js . Quindi, per semplificare questa lunga digitazione, possiamo mettere questo …

     ...

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

     ...

… quindi chiama npm start a usare ‘nodemon’ che ha app.js come primo argomento.

Quello che sto cercando di dire, se vuoi solo avviare il tuo server con il comando node , non penso che tu debba usare gli scripts . La digitazione di npm start o node app.js ha lo stesso sforzo.

Ma se vuoi usare nodemon e vuoi passare un argomento dinamico, non usare neanche lo script . Prova a usare invece symlink.

Ad esempio usando la migrazione con sequelize . Creo un link simbolico …

ln -s node_modules/sequelize/bin/sequelize sequelize

… E posso passare qualsiasi discussione quando la chiamo …

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

eccetera…

A questo punto, usare symlink è il modo migliore che io possa capire, ma non penso che sia la migliore pratica.

Spero anche la tua opinione per la mia risposta.

Ho trovato questa domanda mentre stavo cercando di risolvere il mio problema con l’esecuzione di sequelize seed: generare comando cli:

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

Fammi arrivare al punto. Volevo avere un breve comando di script nel mio file package.json e fornire l’argomento –name allo stesso tempo

La risposta è arrivata dopo alcuni esperimenti. Ecco il mio comando in package.json

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

… ed ecco qui ed un esempio di eseguirlo nel terminale per generare un file seme per un utente

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

FYI

 yarn -v 1.6.0 npm -v 5.6.0