Jak ustawić zmienne środowiskowe z pakietu package.json

313

Jak ustawić niektóre zmienne środowiskowe od wewnątrz package.json aby były używane z npm startpodobnymi poleceniami?

Oto, co obecnie mam w moim package.json:

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

Chcę ustawić zmienne środowiskowe (np NODE_ENV) w skrypcie startowym, a jednocześnie jest w stanie uruchomić aplikację z jednym poleceniu npm start.

dev.meghraj
źródło
Możesz przeczytać tę odpowiedź stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Odpowiedzi:

433

Ustaw zmienną środowiskową w poleceniu skryptowym:

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

Następnie użyj process.env.NODE_ENVw swojej aplikacji.

Uwaga: envzapewnia, że ​​działa na różnych platformach. Możesz go pominąć, jeśli dbasz tylko o Mac / Linux.

cesar
źródło
65
Czy ktoś wymyślił alternatywę dla systemu Windows?
nieskończoność
65
@infinity użyj cross-env i jest bardzo łatwy w użyciu.
mikekidder
106
@ wykorzystanie nieskończoności set NODE_ENV=test&& mocha --reporter spec- celowo nie ma spacji między testem a &&.
Jamie Penney,
18
"test": "NODE_ENV=test mocha --reporter spec"nie będzie działać w systemach Windows.
Benny Neugebauer
7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specużyje zadeklarowanej zmiennej środowiskowej w sposób natywny na wiele platform, ale kluczem jest to, że jest używana przez npm w trybie ad hoc i jednorazowo, tylko do wykonania skryptu npm. (Nie jest ustawiony ani eksportowany do wykorzystania w przyszłości.) Tak długo, jak uruchamiasz polecenie ze skryptu npm, nie ma problemu. Ponadto „&&” należy usunąć, robiąc to w ten sposób.
estaples
219

Wystarczy użyć pakietu NPM cross-env . Super łatwe. Działa w systemach Windows, Linux i wszystkich środowiskach. Zauważ, że nie używasz && do przejścia do następnego zadania. Po prostu ustaw env, a następnie rozpocznij następne zadanie. Kredyt dla @mikekidder za sugestię w jednym z komentarzy tutaj.

Z dokumentacji:

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

Zauważ, że jeśli chcesz ustawić wiele globalnych zmiennych, wystarczy podać je kolejno, a następnie polecenie, które ma zostać wykonane.

Ostatecznie polecenie, które jest wykonywane (za pomocą spawn) to:

webpack --config build/webpack.config.js

NODE_ENVZmienna zostanie ustalona przez cross-ENV

TetraDev
źródło
Potrójne backslashe mogą być wykorzystywane do ewakuacji wymaganych cytatów:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
BVJ
1
Najlepsze rozwiązanie, ponieważ wiele platform.
bernardn
Czy ktoś może mi w końcu pomóc zdecydować, czy powinienem użyć, envczy cross-env? Z jednej strony env nie wymaga ode mnie instalacji, az drugiej strony cross-envjest bardziej popularny. Czy ktoś może potwierdzić, czy envdziała na wszystkich platformach?
Rishav
2
@Rishav envnie działa tak, jak jest na wszystkich platformach, stąd powód cross-envistnienia. Po prostu użyj cross-envi gotowe.
TetraDev
37

Chciałem tylko dodać tutaj dwa centy dla przyszłych eksploratorów węzłów. Na moim Ubuntu 14.04 NODE_ENV=testnie działało, musiałem użyć, export NODE_ENV=testpo czym NODE_ENV=testzacząłem działać, dziwne.

W systemie Windows, jak już powiedziano, musisz używać, set NODE_ENV=testale dla rozwiązania wieloplatformowego biblioteka cross-env nie wydawała się załatwić i czy naprawdę potrzebujesz biblioteki, aby to zrobić:

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

Pionowe paski są potrzebne, ponieważ w przeciwnym razie system Windows zawiesiłby się na nierozpoznanym export NODE_ENVpoleceniu: D. Nie wiem o końcowej spacji, ale dla pewności też je usunąłem.

TeemuK
źródło
6
Czy używałeś &&? NODE_ENV=test yaddaoznacza „uruchom yadda, ustawianie NODE_ENVw yaddazmiennych środowiskowych. NODE_ENV=test && yadda” oznacza „ustaw NODE_ENVw środowisku lokalnym, ale nie eksportuj go, a następnie uruchom yadda.” NODE_ENV=test yaddato preferowane podejście.
Josh Kelley
Przepraszam, że od jakiegoś czasu nie sprawdzałem mojego konta Stackoverflow. Ale w zasadzie głupiutki Windows nie działał przy użyciu NODE_ENV=test && npm run testlub czegoś podobnego. Zrobiłem lepsze rozwiązanie, korzystając z process.env["NODE_ENV"] = "testing";mojego pliku testhelper.js.
TeemuK,
5
@TeemuK tylko po to, by dodać moje dwa centy, kiedy uruchomisz polecenie ze &&straconymi zmiennymi środowiskowymi, ustawienie zmiennych środowiskowych bez eksportu działa tylko na bieżącym poleceniu (co jest niczym). uruchomić polecenie ze zmienną env bez eksportowania u zrobić: NODE_ENV=test npm run test. Wreszcie powodem, dla którego zadziałało po wyeksportowaniu, jest to, że zmienna ur jest teraz dostępna (wyeksportowana) w sesji, więc twój NODE_ENV bez eksportu nic nie robił.
Tarek
37

Ponieważ często pracuję z wieloma zmiennymi środowiskowymi, uważam, że warto je przechowywać w osobnym .envpliku (pamiętaj, aby zignorować to z poziomu kontroli źródła).

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

Następnie dodaj export $(cat .env | xargs) &&przed poleceniem skryptu.

Przykład:

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

Do testu można wyświetlić zmienne env, uruchamiając npm run env(Linux) lub npm run env-windows(Windows).

Łukasz
źródło
Bardzo dobrze, prawie zrobiło to dla mnie robotę! Chciałbym dodać kilka komentarzy: - Nie możesz mieć pustych linii w pliku .env - Komentarze w pliku .env spowodują uszkodzenie skryptu - Jeśli wiele skryptów używa tego samego pliku .env, będziesz musiał powtórzyć - Musiałem wcześniej usunąć to miejsce, &&aby mogło działać - jeśli masz wiele plików .env, może być trochę trudniej utrzymać Twoja odpowiedź zainspirowała mnie do przygotowania tej sugestii: stackoverflow.com/questions/25112510/...
Felipe N Moura
19

Wypróbuj to w systemie Windows, zastępując YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
źródło
1
Tak! Dziękuję Ci! To była odpowiedź, której szukałem! : D
Daniel Tonon,
6
Musiałem usunąć to miejsce przed &&.
Kenneth Solberg
Komentarz @ KennethSolberg był ostatnim akcentem, który sprawił, że zadziałało dla mnie (tylko Windows)
ulu
Ja też miałem problem z przestrzenią. Podczas rejestrowania długości łańcucha mogłem powiedzieć, że spacja została dodana. Próbowałem uniknąć cytatów - i były one faktycznie przechowywane w envar. Próbowałem innych ograniczników bezskutecznie. Jedynym sposobem na obejście tego problemu było usunięcie przestrzeni lub przycięcie wartości, co wydaje mi się złe.
Neil Guy Lindberg
8

nagle odkryłem, że Actionhero używa następującego kodu, który rozwiązał mój problem, przekazując --NODE_ENV=productionopcję polecenia start skryptu.

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

Byłbym naprawdę wdzięczny za przyjęcie odpowiedzi kogoś, kto wie lepiej, jak ustawić zmienne środowiskowe w pakiecie.json lub skrypcie inicjującym lub coś w tym rodzaju, gdzie aplikacja została uruchomiona przez kogoś innego.

dev.meghraj
źródło
4

W przypadku większego zestawu zmiennych środowiskowych lub gdy chcesz ich ponownie użyć, możesz użyć env-cmd .

./.env plik:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
źródło
jak używasz ENV1 w skrypcie?
ValRob,
Zwykleprocess.env.ENV1
KARASZI István
ale w pliku package.json? przeczytałem, że to niemożliwe (?)
ValRob
Nie rozumiem. Dlaczego chcesz to zrobić?
KARASZI István
być może jest to głupie podejście, ale miałem aktualizację macOs Catalina i teraz polecenie mongodb nie działa, więc muszę podać dane / folder mongod --dbpath ~/data/db. Chcę uruchomić coś takiego, npm mongodba to otrzyma zmienną środowiskową dbpath i uruchomi mondodb tak jak zawsze ... i .. chcę udostępnić go innym członkom.
ValRob,
2

Chociaż nie odpowiadam bezpośrednio na pytanie, chciałbym podzielić się pomysłem z innymi odpowiedziami. Z tego, co otrzymałem, każdy z nich oferowałby pewien poziom złożoności w celu osiągnięcia niezależności między platformami.

W moim scenariuszu pierwotnie chciałem ustawić zmienną, aby kontrolować, czy zabezpieczyć serwer za pomocą uwierzytelniania JWT (do celów programistycznych)

Po przeczytaniu odpowiedzi postanowiłem po prostu utworzyć 2 różne pliki z włączonym i wyłączonym uwierzytelnianiem.

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

Pliki to po prostu opakowania, które wywołują oryginalny plik index.js (którego nazwę zmieniłem 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
    }
}

Być może może to pomóc komuś innemu

Luiz Henrique Martins Lins Rol
źródło
2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}
Cailean
źródło
2

Będzie to działać w konsoli Windows :

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

npm run aaa

wynik: test

Zobacz tę odpowiedź, aby uzyskać szczegółowe informacje.

Siergiej
źródło
5
Powinno być set TMP=test&& npm run bbb. Poprzednia przestrzeń &&będzie również zaciskać się w ramach tego NODE_ENVciągu
FisNaN
@FisNaN Nie powinno tak być, jeśli otoczysz go cytatami ".
kaiser
1

Nie należy ustawiać zmiennych ENV w package.json. Actionhero używa, NODE_ENVabyś mógł zmienić opcje konfiguracji, które są ładowane z plików w ./config. Sprawdź plik konfiguracyjny redis i zobacz, jak NODE_ENV używa do zmiany opcji bazy danychNODE_ENV=test

Jeśli chcesz użyć innych zmiennych ENV do ustawienia rzeczy (być może portu HTTP), nadal nie musisz nic zmieniać package.json. Na przykład, jeśli ustawiłeś PORT=1234ENV i chcesz użyć tego jako portu HTTP NODE_ENV=production, po prostu odwołaj się do tego w odpowiednim pliku konfiguracyjnym, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
źródło
świetny. myślę, że nie przeczytałeś mojego pytania. Moim problemem jest ustawienie NODE_ENV, a nie jego użycie.
dev.meghraj,
1
Jeśli chcesz ustawić wiele właściwości środowiska, nie robisz tego w npm startpoleceniu. Korzystanie fragment powyżej, jeśli chcesz uruchomić serwer za pomocą portu ENV byłoby: export PORT=1234; npm start. Możesz dołączyć tyle deklaracji ENV, ile potrzebujesz, ale nie należą one do pliku package.json. Jeśli martwisz się o upewniając się, że istnieje należy użyć domyślnych ustawień w pliku konfiguracyjnym: port: process.env.PORT || 8080.
Tony
1
Być może alternatywnym sposobem wyjaśnienia tego byłoby, że NODE_ENV (i inne zmienne środowiskowe) są częścią środowiska (stąd nazwa). Zazwyczaj są to właściwości serwera, na którym aplikacja jest uruchomiona, a nie aplikacji. Możesz ustawić je ręcznie za pomocą wykonywanego polecenia, tj .: NODE_ENV=test npm startlub ustawić je przy użyciu powłoki
Evan
3
Nie zgadzam się. użycie ./config dla każdego środowiska ogranicza się do korzystania ze środowisk statycznych podczas wdrażania aplikacji. Jest to przestarzała filozofia, która nie pozwoli ci rozruszać nowych typów środowisk w razie potrzeby. IE dla każdego nowego środowiska, które chcesz, będziesz musiał dodać .config. Ustawienie zmiennych środowiskowych w czasie wykonywania może być lepszą opcją, gdy stos technologii wymaga większej elastyczności. Myślę, że twój ./config byłby dobry do konfigurowania „typów” środowisk, ale twoja aplikacja byłaby bardziej elastyczna, gdybyś mógł zdefiniować takie rzeczy jak ciągi dsn i punkty końcowe interfejsu API w czasie wykonywania.
Jesse Greathouse,
@JesseGreathouse - Mam aplikację node.js i muszę ustawić zmienne środowiskowe w czasie wykonywania - w jakim pliku miałbym je ustawić?
Roger Dodger,
1

npm (i przędza) przekazuje wiele danych z package.json do skryptów jako zmienne środowiskowe. Użyj, npm run envaby zobaczyć je wszystkie. Jest to udokumentowane w https://docs.npmjs.com/misc/scripts#environment i dotyczy nie tylko skryptów „cyklu życia”, prepublishale także każdego skryptu wykonywanego przez npm run.

Możesz uzyskać dostęp do tych wewnętrznych kodów (np. process.env.npm_package_config_portW JS), ale są one już dostępne dla powłoki wykonującej skrypty, więc możesz również uzyskać do nich dostęp jako $npm_...rozszerzenia w „skryptach” (składnia unixowa, może nie działać w systemie Windows?).

Sekcja „config” wydaje się przeznaczona do tego zastosowania:

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

Ważną cechą tych pól „config” jest to, że użytkownicy mogą je zastąpić bez modyfikowania pliku 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

Zobacz dokumentację konfiguracji npm config i przędzy .
Wygląda na to, że przędza czyta, ~/.npmrcwięc npm config setwpływa na oba, ale yarn config setpisze ~/.yarnrc, więc tylko przędza to zobaczy :-(

Beni Cherniavsky-Paskin
źródło
1

Odpowiedź Luke'a była prawie taka, jakiej potrzebowałem! Dzięki.

Ponieważ wybrana odpowiedź jest bardzo prosta (i poprawna), ale stara, chciałbym zaoferować alternatywę dla importowania zmiennych z osobnego pliku .env podczas uruchamiania skryptów i naprawienia pewnych ograniczeń odpowiedzi Luke'a. Spróbuj tego:

::: plik .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"

Następnie w pakiecie json utworzysz skrypt, który ustawi zmienne i uruchom go przed skryptami, których potrzebujesz:

::: package.json :::

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

Niektóre spostrzeżenia:

  • Wyrażenie regularne w poleceniu grep'ed cat usunie komentarze i puste linie.

  • &&Nie muszą być „przyklejony” do npm run set-env, jak to jest wymagane, jeśli zostały ustawienie zmiennych w tej samej komendy.

  • Jeśli używasz przędzy, możesz zobaczyć ostrzeżenie, możesz ją zmienić na yarn set-envlub użyć npm run set-env --scripts-prepend-node-path &&zamiast tego.

Różne środowiska

Kolejną zaletą korzystania z niego jest to, że możesz mieć różne zmienne środowiskowe.

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

Pamiętaj, aby nie dodawać plików .env do repozytorium git, gdy masz w nich klucze, hasła lub sensowne / osobiste dane!

Felipe N Moura
źródło
1

użyj git bash w Windows. Git Bash przetwarza polecenia inaczej niż cmd.

Większość podpowiedzi poleceń systemu Windows dusi się podczas ustawiania zmiennych środowiskowych za pomocą NODE_ENV = produkcja w ten sposób. (Wyjątkiem jest Bash w Windows, który używa natywnego Bash.) Podobnie, istnieje różnica w sposobie wykorzystania zmiennych środowiskowych przez komendy Windows i POSIX. W systemie POSIX używasz: $ ENV_VAR, a w systemie Windows używasz% ENV_VAR%. - cross-env doc

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

użyj pakietu dotenv, aby zadeklarować zmienne env

Shubham Shaw
źródło