Come impostare le variabili di ambiente all'interno di package.json


313

Come impostare alcune variabili d'ambiente dall'interno package.jsonda usare con npm startcomandi simili?

Ecco cosa ho attualmente nel mio package.json:

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "tagove start"
  }
  ...
}

Voglio variabili d'ambiente set (come NODE_ENV) nello script di avvio, pur essendo in grado di avviare l'applicazione con un solo comando, npm start.


Risposte:


434

Impostare la variabile di ambiente nel comando script:

...
"scripts": {
  "start": "node app.js",
  "test": "env NODE_ENV=test mocha --reporter spec"
},
...

Quindi utilizzare process.env.NODE_ENVnella tua app.

Nota: envassicura che funzioni su tutte le piattaforme. Puoi ometterlo se ti interessa solo Mac / Linux.


65
Qualcuno ha capito un supplente per Windows ..?
infinito

65
@infinity usa cross-env ed è molto facile da usare.
mikekidder,

106
@infinity use set NODE_ENV=test&& mocha --reporter spec- non c'è spazio tra il test e && di proposito.
Jamie Penney,

18
"test": "NODE_ENV=test mocha --reporter spec"non funzionerà su sistemi Windows.
Benny Neugebauer,

7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specutilizzerà la variabile d'ambiente dichiarata in modo nativamente multipiattaforma, ma la chiave è che viene utilizzata da npm in modo ad hoc e una tantum, solo per l'esecuzione dello script npm. (Non è impostato o esportato per riferimento futuro.) Finché si esegue il comando dallo script npm, non vi è alcun problema. Inoltre, "&&" deve essere rimosso quando lo si fa in questo modo.
estaps

219

Basta usare il pacchetto NPM cross-env . Super facile. Funziona su Windows, Linux e tutti gli ambienti. Nota che non usi && per passare all'attività successiva. Basta impostare l'ENV e quindi avviare l'attività successiva. Ringraziamo @mikekidder per il suggerimento in uno dei commenti qui.

Dalla documentazione:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production OTHERFLAG=myValue webpack --config build/webpack.config.js"
  }
}

Si noti che se si desidera impostare più variabili globali, è sufficiente dichiararle in successione, seguite dal comando da eseguire.

Alla fine, il comando che viene eseguito (usando spawn) è:

webpack --config build/webpack.config.js

La NODE_ENVvariabile d'ambiente verrà impostata da cross-env


Le barre rovesciate triple possono essere utilizzate per sfuggire alle citazioni richieste:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj

1
La migliore soluzione perché multipiattaforma.
bernardn

Qualcuno può finalmente aiutarmi a decidere se dovrei usare envo cross-env? Da un lato, env non mi richiede di installare nulla e dall'altro cross-envè più popolare. Qualcuno può confermare se envfunziona su tutte le piattaforme?
Rishav

2
@Rishav envnon funziona così com'è su tutte le piattaforme, quindi il motivo per cross-envesistere. Basta usare cross-enved essere fatto con esso.
TetraDev,

38

Poiché spesso mi trovo a lavorare con più variabili di ambiente, trovo utile tenerle in un .envfile separato (assicurati di ignorarlo dal tuo controllo del codice sorgente).

VAR_A=Hello World
VAR_B=format the .env file like this with new vars separated by a line break

Quindi anteporre export $(cat .env | xargs) &&prima del comando di script.

Esempio:

{
  ...
  "scripts": {
    ...
    "start": "export $(cat .env | xargs) && echo do your thing here",
    "env": "export $(cat .env | xargs) && env",
    "env-windows": "export $(cat .env | xargs) && set"
  }
  ...
}

Per un test è possibile visualizzare le variabili env eseguendo npm run env(linux) o npm run env-windows(windows).


1
Molto bene, ha quasi fatto il lavoro per me! Vorrei aggiungere alcuni commenti: - Non puoi avere righe vuote nel tuo file .env - I commenti nel tuo file .env interromperanno il tuo script - Se più script utilizzano lo stesso file .env, dovrai ripetere che - Prima ho dovuto rimuovere lo spazio &&perché funzionasse - Se hai più file .env, potrebbe essere un po 'più difficile mantenere la tua risposta mi ha ispirato a preparare questo suggerimento: stackoverflow.com/questions/25112510/…
Felipe N Moura

37

Volevo solo aggiungere i miei due centesimi qui per i futuri esploratori di nodi. Sul mio Ubuntu 14.04 NODE_ENV=testnon funzionava, dovevo usare anche export NODE_ENV=testdopo che ha NODE_ENV=testiniziato a funzionare, strano.

Su Windows, come è stato detto, devi usare, set NODE_ENV=testma per una soluzione multipiattaforma la libreria cross-env non sembra fare il trucco e hai davvero bisogno di una libreria per farlo:

export NODE_ENV=test || set NODE_ENV=test&& yadda yadda

Le barre verticali sono necessarie altrimenti Windows si arresterebbe in modo anomalo sul export NODE_ENVcomando non riconosciuto : D. Non so per lo spazio finale ma solo per essere sicuro di averlo rimosso anche io.


6
Hai usato &&? NODE_ENV=test yaddasignifica "esegui yadda, impostando NODE_ENVall'interno yaddadelle variabili di ambiente. NODE_ENV=test && yaddasignifica" imposta NODE_ENVall'interno dell'ambiente locale, ma non esportarlo, quindi esegui yadda" NODE_ENV=test yaddaè l'approccio preferito.
Josh Kelley,

Spiacenti, non ho controllato il mio account StackOverflow da un po 'di tempo. Ma sostanzialmente stupido Windows non ha funzionato usando NODE_ENV=test && npm run testo qualcosa di simile. Ho creato una soluzione migliore usando process.env["NODE_ENV"] = "testing";all'interno del mio file testhelper.js.
TeemuK,

5
@TeemuK solo per aggiungere anche i miei due centesimi, quando esegui il comando con &&te hai perso le variabili di ambiente, l'impostazione delle variabili di ambiente senza esportazione funziona solo sul comando corrente (che è nulla). per eseguire il comando con la variabile ENV senza esportare u fare: NODE_ENV=test npm run test. Infine, il motivo per cui ha funzionato dopo l'esportazione è perché la tua variabile è ora disponibile (esportata) nella sessione, il tuo NODE_ENV senza esportazione non stava facendo nulla.
Tarek,

19

Prova questo su Windows sostituendo YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }

1
Sì! Grazie! Questa era la risposta che stavo cercando! : D
Daniel Tonon,

6
Ho dovuto rimuovere lo spazio prima di &&.
Kenneth Solberg,

Il commento di KennethSolberg è stato il tocco finale che mi ha fatto funzionare (solo Windows)
ulu

Anch'io ho avuto il problema di spazio. Quando si registra la lunghezza della stringa, posso dire che lo spazio viene aggiunto. Ho provato le virgolette sfuggite - ed erano effettivamente archiviate nell'envar. Ho provato altri delimitatori inutilmente. Rimuovere lo spazio o tagliare il valore, che mi sembra sbagliato, erano gli unici modi per aggirare questo problema.
Neil Guy Lindberg,

8

improvvisamente ho scoperto che actionhero sta usando il seguente codice, che ha risolto il mio problema semplicemente passando l' --NODE_ENV=productionopzione di comando start script.

if(argv['NODE_ENV'] != null){
  api.env = argv['NODE_ENV'];
} else if(process.env.NODE_ENV != null){
  api.env = process.env.NODE_ENV;
}

apprezzerei davvero accettare la risposta di qualcun altro che conosce un modo migliore per impostare le variabili di ambiente in package.json o script di script o qualcosa del genere, in cui l'app viene avviata da qualcun altro.


4

Per un set più ampio di variabili di ambiente o quando si desidera riutilizzarle, è possibile utilizzarle env-cmd.

./.env file:

# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}

come si usa ENV1 nello script?
ValRob,

Il solitoprocess.env.ENV1
KARASZI István,

ma, all'interno del package.json? avevo letto che è impossibile (?)
ValRob il

Non capisco. Perché dovresti farlo?
KARASZI István,

forse è un approccio sciocco, ma ho dovuto aggiornare macOs Catalina e ora il comando mongodb non funziona, quindi ho bisogno di specificare i dati / la cartella mongod --dbpath ~/data/db. Voglio eseguire qualcosa del genere npm mongodbe questo otterrà la variabile d'ambiente dbpath ed eseguirà il mondodb come sempre ... e ... voglio condividerlo con altri membri.
ValRob,

2

Pur non rispondendo direttamente alla domanda, vorrei condividere un'idea in cima alle altre risposte. Da quello che ho ottenuto ognuno di questi offrirebbe un certo livello di complessità per raggiungere l'indipendenza tra le piattaforme.

Nel mio scenario tutto ciò che volevo, in origine, impostare una variabile per controllare se proteggere il server con l'autenticazione JWT (a fini di sviluppo)

Dopo aver letto le risposte ho deciso semplicemente di creare 2 file diversi, con l'autenticazione attivata e disattivata rispettivamente.

  "scripts": {
    "dev": "nodemon --debug  index_auth.js",
    "devna": "nodemon --debug  index_no_auth.js",
  }

I file sono semplicemente wrapper che chiamano il file index.js originale (a cui ho rinominato appbootstrapper.js):

//index_no_auth.js authentication turned off
const bootstrapper = require('./appbootstrapper');
bootstrapper(false);

//index_auth.js authentication turned on
const bootstrapper = require('./appbootstrapper');
bootstrapper(true);

class AppBootStrapper {

    init(useauth) {
        //real initialization
    }
}

Forse questo può aiutare qualcun altro


2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}

2

Questo funzionerà nella console di Windows :

"scripts": {
  "aaa": "set TMP=test && npm run bbb",
  "bbb": "echo %TMP%"
}

npm run aaa

produzione: test

Vedi questa risposta per i dettagli.


5
Dovrebbe essere set TMP=test&& npm run bbb. Lo spazio precedente &&verrà anche conteggiato come parte della NODE_ENVstringa successiva
FisNaN,

@FisNaN Non dovrebbe essere il caso se lo circondi tra virgolette ".
Kaiser

2

usa git bash in windows. Git Bash elabora i comandi in modo diverso da cmd.

La maggior parte dei prompt dei comandi di Windows si bloccherà quando si impostano le variabili di ambiente con NODE_ENV = produzione simile. (L'eccezione è Bash su Windows, che utilizza Bash nativo.) Allo stesso modo, c'è una differenza nel modo in cui Windows e i comandi POSIX utilizzano le variabili di ambiente. Con POSIX, usi: $ ENV_VAR e su Windows usi% ENV_VAR%. - cross-env doc

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "env NODE_ENV=production tagove start"
  }
  ...
}

usa il pacchetto dotenv per dichiarare le variabili env


1

Non è necessario impostare le variabili ENV in package.json. actionhero utilizza NODE_ENVper consentire di modificare le opzioni di configurazione che vengono caricate dai file in ./config. Controlla il file di configurazione redis e guarda come viene utilizzato NODE_ENV per modificare le opzioni del databaseNODE_ENV=test

Se vuoi usare altre variabili ENV per impostare le cose (forse la porta HTTP), non hai ancora bisogno di cambiare nulla package.json. Ad esempio, se si imposta PORT=1234ENV e si desidera utilizzarlo come porta HTTP in NODE_ENV=production, basta fare riferimento a quello nel relativo file di configurazione, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}

grande. penso che non hai letto la mia domanda .. il mio problema è come impostare NODE_ENV e non a cosa serve.
dev.meghraj,

1
Se si desidera impostare più proprietà dell'ambiente, non farlo nel npm startcomando. Utilizzando questo frammento di codice, se si voleva eseguire il server utilizzando la porta ENV sarebbe: export PORT=1234; npm start. Puoi aggiungere tutte le dichiarazioni ENV di cui hai bisogno, ma non appartengono al file package.json. Se siete preoccupati per fare in modo che esistono si dovrebbe usare le impostazioni predefinite nel file di configurazione: port: process.env.PORT || 8080.
Tony

1
Forse un modo alternativo per spiegare questo sarebbe che NODE_ENV (e altre variabili d'ambiente) fanno parte dell'ambiente (da cui il nome). Di solito sono proprietà del server su cui si sta eseguendo l'applicazione anziché dell'applicazione. Puoi impostarli manualmente tramite il comando che esegui, ovvero: NODE_ENV=test npm starto impostali dalla shell
Evan

3
Non sono d'accordo. l'utilizzo di un ./config per ogni ambiente ti limita all'uso di ambienti statici durante la distribuzione della tua app. Questa è una filosofia obsoleta che non ti permetterà di creare nuovi tipi di ambienti quando necessario. IE per ogni nuovo ambiente che desideri, dovrai aggiungere un .config. L'impostazione delle variabili di ambiente in fase di esecuzione può essere un'opzione superiore quando lo stack tecnologico richiede maggiore flessibilità. Penso che il tuo ./config sarebbe utile per impostare "tipi" di ambienti, ma la tua app sarebbe più flessibile se potessi definire cose come stringhe DSN e endpoint API in fase di esecuzione.
Jesse Greathouse,

@JesseGreathouse - Ho un'applicazione node.js e devo impostare le variabili di ambiente in fase di runtime - in quale file dovrei inserirle?
Roger Dodger,

1

npm (e thread) passa molti dati da package.json negli script come variabili di ambiente. Usalo npm run envper vederli tutti. Questo è documentato in https://docs.npmjs.com/misc/scripts#environment e non è solo per script "del ciclo di vita" come prepublishma anche qualsiasi script eseguito da npm run.

Puoi accedere a questi codici interni (ad esempio process.env.npm_package_config_portin JS) ma sono già disponibili per la shell che esegue gli script in modo da poterli accedere anche come $npm_...espansioni negli "script" (sintassi unix, potrebbe non funzionare su Windows?).

La sezione "config" sembra destinata a questo uso:

  "name": "myproject",
  ...
  "config": {
    "port": "8010"
  },
  "scripts": {
    "start": "node server.js $npm_package_config_port",
    "test": "wait-on http://localhost:$npm_package_config_port/ && node test.js http://localhost:$npm_package_config_port/"
  } 

Una qualità importante di questi campi "config" è che gli utenti possono sovrascriverli senza modificare package.json !

$ npm run start

> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8010

$ npm config set myproject:port 8020
$ git diff package.json  # no change!
$ cat ~/.npmrc
myproject:port=8020

$ npm run start

> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8020

Vedi i documenti di configurazione di npm config e filato .
Sembra che il filato legga ~/.npmrccosì npm config setinfluisce su entrambi, ma yarn config setscrive ~/.yarnrc, quindi solo il filato lo vedrà :-(


1

La risposta di @ luke era quasi quella di cui avevo bisogno! Grazie.

Dato che la risposta selezionata è molto semplice (e corretta), ma vecchia, vorrei offrire un'alternativa per importare variabili da un file separato .env quando esegui i tuoi script e correggi alcune limitazioni alla risposta di Luke. Prova questo:

::: File .env :::

# This way, you CAN use comments in your .env files
NODE_PATH="src/"

# You can also have extra/empty lines in it
SASS_PATH="node_modules:src/styles"

Quindi, nel tuo pacchetto json, creerai uno script che imposterà le variabili e lo eseguirà prima degli script che ti servono:

::: package.json :::

scripts: {
  "set-env": "export $(cat .env | grep \"^[^#;]\" |xargs)",
  "storybook": "npm run set-env && start-storybook -s public"
}

Alcune osservazioni:

  • L'espressione regolare nel comando grep'ed cat cancellerà i commenti e le righe vuote.

  • Il &&non hanno bisogno di essere "incollati" a npm run set-env, in quanto sarebbe necessario se imposti le variabili nello stesso comando.

  • Se stai usando un filo, potresti vedere un avviso, puoi cambiarlo yarn set-envo usarlo npm run set-env --scripts-prepend-node-path &&.

Ambienti diversi

Un altro vantaggio quando lo si utilizza è che è possibile avere diverse variabili di ambiente.

scripts: {
  "set-env:production": "export $(cat .production.env | grep \"^[^#;]\" |xargs)",
  "set-env:development": "export $(cat .env | grep \"^[^#;]\" |xargs)",
}

Ricorda di non aggiungere file .env al tuo repository git quando hai chiavi, password o dati sensibili / personali in essi!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.