So legen Sie Umgebungsvariablen in package.json fest

313

Wie setze package.jsonich einige Umgebungsvariablen von innen , um sie mit npm startähnlichen Befehlen zu verwenden?

Folgendes habe ich derzeit in meinem package.json:

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

Ich möchte Umgebungsvariablen (wie NODE_ENV) im Startskript festlegen und gleichzeitig die App mit nur einem Befehl starten können npm start.

dev.meghraj
quelle
Sie können diese Antwort lesen stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Antworten:

433

Legen Sie die Umgebungsvariable im Skriptbefehl fest:

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

Dann verwenden Sie process.env.NODE_ENVin Ihrer App.

Hinweis: envStellt sicher, dass es plattformübergreifend funktioniert. Sie können es weglassen, wenn Sie sich nur für Mac / Linux interessieren.

Cesar
quelle
65
Hat jemand eine Alternative für Windows gefunden ..?
Unendlichkeit
65
@infinity verwendet cross-env und ist sehr einfach zu bedienen.
Mikekidder
106
@infinity use set NODE_ENV=test&& mocha --reporter spec- Zwischen dem Test und && ist absichtlich kein Leerzeichen.
Jamie Penney
18
"test": "NODE_ENV=test mocha --reporter spec"funktioniert nicht auf Windows-Systemen.
Benny Neugebauer
7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specverwendet die deklarierte Umgebungsvariable nativ plattformübergreifend. Der Schlüssel ist jedoch, dass sie von npm ad hoc und einmalig nur für die Ausführung des npm-Skripts verwendet wird. (Es wird nicht festgelegt oder zur späteren Bezugnahme exportiert.) Solange Sie Ihren Befehl über das npm-Skript ausführen, gibt es kein Problem. Außerdem muss das "&&" entfernt werden, wenn Sie dies auf diese Weise tun.
estaples
219

Verwenden Sie einfach das NPM-Paket cross-env . Super einfach. Funktioniert unter Windows, Linux und allen Umgebungen. Beachten Sie, dass Sie && nicht verwenden, um zur nächsten Aufgabe zu gelangen. Sie legen einfach die Umgebung fest und starten dann die nächste Aufgabe. Dank an @mikekidder für den Vorschlag in einem der Kommentare hier.

Aus der Dokumentation:

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

Beachten Sie, dass Sie, wenn Sie mehrere globale Variablen festlegen möchten, diese nur nacheinander angeben, gefolgt von Ihrem auszuführenden Befehl.

Letztendlich lautet der Befehl, der ausgeführt wird (mit Spawn):

webpack --config build/webpack.config.js

Die NODE_ENVUmgebungsvariable wird von cross-env festgelegt

TetraDev
quelle
Dreifache Backslashes können verwendet werden, um erforderlichen Anführungszeichen zu entgehen:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj
1
Beste Lösung, weil plattformübergreifend.
Bernard
Kann mir endlich jemand bei der Entscheidung helfen, ob ich envoder verwenden soll cross-env? Einerseits erfordert env nicht, dass ich etwas installiere, und andererseits cross-envist es beliebter. Kann jemand bitte bestätigen, ob envauf allen Plattformen funktioniert?
Rishav
2
@Rishav envfunktioniert nicht auf allen Plattformen wie es ist, daher der Grund für cross-envdie Existenz. Einfach benutzen cross-envund fertig.
TetraDev
37

Ich wollte hier nur meine zwei Cent für zukünftige Node-Entdecker hinzufügen. Auf meinem Ubuntu 14.04 NODE_ENV=testfunktionierte das nicht, ich musste es verwenden, export NODE_ENV=testdanach NODE_ENV=testfing es auch an zu arbeiten, komisch.

Unter Windows müssen Sie, wie bereits gesagt, verwendet werden, set NODE_ENV=testaber für eine plattformübergreifende Lösung schien die Cross-Env-Bibliothek nicht den Trick zu tun, und benötigen Sie dazu wirklich eine Bibliothek:

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

Die vertikalen Balken werden benötigt, da Windows sonst bei dem nicht erkannten export NODE_ENVBefehl abstürzen würde : D. Keine Ahnung über den nachgestellten Platz, aber nur um sicherzugehen, dass ich sie auch entfernt habe.

TeemuK
quelle
6
Hast du benutzt &&? NODE_ENV=test yaddabedeutet "Ausführen yadda, Festlegen NODE_ENVinnerhalb yaddader Umgebungsvariablen. NODE_ENV=test && yaddaBedeutet" In NODE_ENVder lokalen Umgebung festlegen , aber nicht exportieren, dann ausführen yadda". Dies NODE_ENV=test yaddaist der bevorzugte Ansatz.
Josh Kelley
Entschuldigung, dass ich mein Stackoverflow-Konto seit einiger Zeit nicht mehr überprüft habe. Aber im Grunde hat dummes Windows nicht funktioniert NODE_ENV=test && npm run testoder ähnliches. Ich habe eine bessere Lösung mit process.env["NODE_ENV"] = "testing";meiner Datei testhelper.js gefunden.
TeemuK
5
@TeemuK, nur um meine zwei Cent hinzuzufügen, wenn Sie Ihren Befehl ausführen &&und Ihre Umgebungsvariablen verloren haben, funktioniert das Festlegen von Umgebungsvariablen ohne Export nur mit dem aktuellen Befehl (was nichts ist). Um den Befehl mit der Variablen env auszuführen, ohne u zu exportieren, tun Sie Folgendes : NODE_ENV=test npm run test. Der Grund, warum es nach dem Export funktioniert hat, ist, dass Ihre Variable jetzt in der Sitzung verfügbar (exportiert) ist und Ihr NODE_ENV ohne Export nichts getan hat.
Tarek
37

Da ich häufig mit mehreren Umgebungsvariablen arbeite, finde ich es nützlich, sie in einer separaten .envDatei zu speichern (ignorieren Sie dies in Ihrer Quellcodeverwaltung).

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

Stellen Sie dann export $(cat .env | xargs) &&vor Ihrem Skriptbefehl ein.

Beispiel:

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

Für einen Test können Sie die env-Variablen anzeigen, indem Sie npm run env(Linux) oder npm run env-windows(Windows) ausführen .

Luke
quelle
Sehr gut, es hat fast den Job für mich gemacht! Ich möchte ein paar Kommentare hinzufügen: - Sie können keine leeren Zeilen in Ihrer .env-Datei haben. - Kommentare in Ihrer .env-Datei beschädigen Ihr Skript. - Wenn mehrere Skripte dieselbe .env-Datei verwenden, müssen Sie dies wiederholen. - Ich musste den Speicherplatz entfernen, bevor &&es funktioniert. - Wenn Sie mehrere .env-Dateien haben, ist es möglicherweise etwas schwieriger, diese zu pflegen. Ihre Antwort hat mich dazu inspiriert, diesen Vorschlag vorzubereiten: stackoverflow.com/questions/25112510/…
Felipe N Moura
19

Versuchen Sie dies unter Windows, indem Sie Folgendes ersetzen YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
quelle
1
Ja! Danke dir! Dies war die Antwort, nach der ich gesucht habe! : D
Daniel Tonon
6
Ich musste den Platz vor && entfernen.
Kenneth Solberg
@ KennethSolbergs Kommentar war der letzte Schliff, der es für mich (nur Windows) zum
Laufen brachte
Ich hatte auch das Platzproblem. Beim Protokollieren der Zeichenfolgenlänge konnte ich feststellen, dass Leerzeichen hinzugefügt wurden. Ich habe versucht, entkommene Zitate zu verwenden - und sie wurden tatsächlich im Envar gespeichert. Ich habe andere Trennzeichen ohne Erfolg ausprobiert. Das Entfernen des Leerzeichens oder das Trimmen des Werts, was sich für mich falsch anfühlt, waren die einzigen Möglichkeiten, um dieses Problem zu umgehen.
Neil Guy Lindberg
8

Plötzlich stellte ich fest, dass actionhero folgenden Code verwendet, der mein Problem löste, indem er einfach die Befehlsoption --NODE_ENV=productionstart script übergab .

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

Ich würde es wirklich begrüßen, die Antwort von jemand anderem zu akzeptieren, der besser weiß, wie Umgebungsvariablen in package.json oder im Init-Skript oder so etwas gesetzt werden können, wenn die App von jemand anderem gebootet wird.

dev.meghraj
quelle
4

Für einen größeren Satz von Umgebungsvariablen oder wenn Sie sie wiederverwenden möchten, können Sie verwenden env-cmd.

./.env Datei:

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

./package.json::

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
quelle
Wie benutzt man ENV1 im Skript?
ValRob
Das Üblicheprocess.env.ENV1
KARASZI István
aber in der package.json? Ich hatte gelesen, dass das unmöglich ist (?)
ValRob
Ich verstehe nicht. Warum würdest du das tun?
KARASZI István
Vielleicht ist das ein dummer Ansatz, aber ich hatte die MacOs Catalina aktualisiert und jetzt funktioniert der Befehl mongodb nicht mehr, also muss ich die Daten / den Ordner angeben mongod --dbpath ~/data/db. Ich möchte so etwas ausführen npm mongodbund das wird die Umgebungsvariable dbpath erhalten und die Mondodb wie immer ausführen ... und ... ich möchte es mit anderen Mitgliedern teilen.
ValRob
2

Obwohl ich die Frage nicht direkt beantworte, möchte ich eine Idee zusätzlich zu den anderen Antworten teilen. Von dem, was ich bekommen habe, würde jedes dieser Elemente ein gewisses Maß an Komplexität bieten, um plattformübergreifende Unabhängigkeit zu erreichen.

In meinem Szenario wollte ich ursprünglich nur eine Variable festlegen, um zu steuern, ob der Server mit JWT-Authentifizierung (für Entwicklungszwecke) gesichert werden soll oder nicht.

Nachdem ich die Antworten gelesen hatte, entschied ich mich einfach, zwei verschiedene Dateien mit aktivierter bzw. deaktivierter Authentifizierung zu erstellen.

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

Die Dateien sind einfach Wrapper, die die ursprüngliche Datei index.js aufrufen (in die ich umbenannt habe 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
    }
}

Vielleicht kann das jemand anderem helfen

Luiz Henrique Martins Lins Rol
quelle
2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}
Cailean
quelle
2

Dies funktioniert in der Windows-Konsole :

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

npm run aaa

Ausgabe: test

Siehe diese Antwort für Details.

Sergey
quelle
5
Sollte sein set TMP=test&& npm run bbb. Das Leerzeichen vor &&wird auch als Teil der damaligen NODE_ENVZeichenfolge
FisNaN
@FisNaN Sollte nicht der Fall sein, wenn Sie es mit Anführungszeichen umgeben ".
Kaiser
1

Sie sollten keine ENV-Variablen in setzen package.json. Mit actionhero NODE_ENVkönnen Sie Konfigurationsoptionen ändern, die aus den Dateien in geladen werden ./config. Überprüfen Sie die Redis-Konfigurationsdatei und sehen Sie, wie NODE_ENV zum Ändern der Datenbankoptionen in verwendet wirdNODE_ENV=test

Wenn Sie andere ENV-Variablen verwenden möchten, um Dinge festzulegen (möglicherweise den HTTP-Port), müssen Sie immer noch nichts ändern package.json. Wenn Sie beispielsweise PORT=1234in ENV festlegen und dies als HTTP-Port in verwenden möchten NODE_ENV=production, verweisen Sie einfach auf das in der entsprechenden Konfigurationsdatei, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
quelle
großartig. Ich denke, Sie haben meine Frage nicht gelesen. Mein Problem ist, wie man NODE_ENV setzt, nicht was davon verwendet wird.
dev.meghraj
1
Wenn Sie mehrere Umgebungseigenschaften festlegen möchten, tun Sie dies nicht im npm startBefehl. Wenn Sie mit dem obigen Snippet Ihren Server über den ENV-Port ausführen möchten, ist dies : export PORT=1234; npm start. Sie können beliebig viele ENV-Deklarationen anhängen, diese gehören jedoch nicht in die Datei package.json. Wenn Sie sich Sorgen machen möchten, dass sie vorhanden sind, sollten Sie die Standardeinstellungen in Ihrer Konfigurationsdatei verwenden : port: process.env.PORT || 8080.
Tony
1
Eine alternative Möglichkeit, dies zu erklären, wäre möglicherweise, dass NODE_ENV (und andere Umgebungsvariablen) Teil der Umgebung sind (daher der Name). Dies sind normalerweise Eigenschaften des Servers, auf dem Sie die Anwendung ausführen, und nicht Ihrer Anwendung. Sie können sie manuell über den Befehl festlegen, den Sie ausführen, dh: NODE_ENV=test npm startoder sie von der Shell festlegen lassen
Evan
3
Ich bin nicht einverstanden. Wenn Sie für jede Umgebung eine ./config verwenden, können Sie bei der Bereitstellung Ihrer App nur statische Umgebungen verwenden. Dies ist eine veraltete Philosophie, die es Ihnen nicht ermöglicht, bei Bedarf neue Arten von Umgebungen zu starten. IE für jede neue Umgebung, die Sie möchten, müssen Sie eine .config hinzufügen. Das Festlegen von Umgebungsvariablen zur Laufzeit kann eine überlegene Option sein, wenn Ihr Tech-Stack mehr Flexibilität erfordert. Ich denke, Ihre ./config wäre gut für die Einrichtung von "Arten" von Umgebungen, aber Ihre App wäre flexibler, wenn Sie zur Laufzeit Dinge wie dsn-Strings und API-Endpunkte definieren könnten.
Jesse Greathouse
@JesseGreathouse - Ich habe eine Anwendung node.js und muss die Umgebungsvariablen zur Laufzeit festlegen. In welcher Datei würde ich sie festlegen?
Roger Dodger
1

npm (und Garn) übergibt viele Daten aus package.json als Umgebungsvariablen an Skripte. Verwenden Sie npm run env, um sie alle zu sehen. Dies ist in https://docs.npmjs.com/misc/scripts#environment dokumentiert und gilt nicht nur für "Lifecycle" -Skripte wie, prepublishsondern auch für alle von npm run.

Sie können auf diesen internen Code zugreifen (z. B. process.env.npm_package_config_portin JS), aber sie stehen der Shell, in der die Skripte ausgeführt werden, bereits zur Verfügung, sodass Sie auch als $npm_...Erweiterungen in den "Skripten" darauf zugreifen können (Unix-Syntax funktioniert unter Windows möglicherweise nicht?).

Der Abschnitt "config" scheint für diese Verwendung vorgesehen zu sein:

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

Eine wichtige Eigenschaft dieser "Konfigurations" -Felder ist, dass Benutzer sie überschreiben können, ohne package.json zu ändern !

$ 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

Siehe npm config und yarn config docs.
Es scheint , dass Garn liest ~/.npmrcso npm config setbeide betrifft, sondern yarn config setschreibt ~/.yarnrc, so dass nur Garn es sieht :-(

Beni Cherniavsky-Paskin
quelle
1

@ lukes Antwort war fast die, die ich brauchte! Vielen Dank.

Da die ausgewählte Antwort sehr einfach (und korrekt), aber alt ist, möchte ich eine Alternative zum Importieren von Variablen aus einer separaten .env-Datei anbieten, wenn Sie Ihre Skripte ausführen und einige Einschränkungen für Lukes Antwort beheben. Versuche dies:

::: .env Datei :::

# 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"

Anschließend erstellen Sie in Ihrem Paket json ein Skript, mit dem die Variablen festgelegt und vor den Skripten ausgeführt werden, die Sie benötigen:

::: package.json :::

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

Einige Beobachtungen:

  • Der reguläre Ausdruck im Befehl grep'ed cat löscht die Kommentare und Leerzeilen.

  • Das &&nicht sein muß „kleben“ zu npm run set-env, wie es erforderlich wäre , wenn Sie die Variablen in dem gleichen Befehl wurden Einstellung.

  • Wenn Sie Garn verwenden, wird möglicherweise eine Warnung angezeigt. Sie können diese entweder ändern yarn set-envoder npm run set-env --scripts-prepend-node-path &&stattdessen verwenden.

Unterschiedliche Umgebungen

Ein weiterer Vorteil bei der Verwendung ist, dass Sie verschiedene Umgebungsvariablen haben können.

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

Bitte denken Sie daran, Ihrem Git-Repository keine .env-Dateien hinzuzufügen, wenn Sie Schlüssel, Passwörter oder vernünftige / persönliche Daten enthalten!

Felipe N Moura
quelle
1

Verwenden Sie Git Bash in Windows. Git Bash verarbeitet Befehle anders als cmd.

Die meisten Windows-Eingabeaufforderungen werden erstickt, wenn Sie Umgebungsvariablen mit NODE_ENV = Produktion so festlegen. (Die Ausnahme ist Bash unter Windows, das natives Bash verwendet.) Ebenso gibt es einen Unterschied darin, wie Windows- und POSIX-Befehle Umgebungsvariablen verwenden. Unter POSIX verwenden Sie: $ ENV_VAR und unter Windows% ENV_VAR%. - cross-env doc

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

Verwenden Sie das Paket dotenv, um die env-Variablen zu deklarieren

Shubham Shaw
quelle