Menu

process.env w Node.js: odczyt zmiennych środowiskowych

process.env to obiekt ze zmiennymi środowiskowymi, z którymi uruchomiono twój program Node.js. Każda wartość to string albo undefined, więc liczby i wartości logiczne zamieniasz sam, a każdej zmiennej dajesz wartość domyślną.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

process.env to obiekt z jedną właściwością na każdą zmienną środowiskową, którą powłoka przekazała twojemu programowi Node.js: process.env.PORT, process.env.DATABASE_URL i tak dalej. Zmienna, której nie ustawiono, ma wartość undefined, a ustawiona zmienna to zawsze string. Odczytaj ją raz przy starcie, daj jej wartość domyślną i zamień na typ, którego potrzebujesz.

Wypisało shop on port 8080 in eu-west (REGION nigdy nie ustawiono, więc zadziałała wartość domyślna), a potem string number: zmienna jest tekstem, dopóki Number() jej nie zamieni. Usuń dwa pierwsze przypisania i uruchom ponownie, żeby zobaczyć wszystkie wartości domyślne.

Ustawianie zmiennych środowiskowych w powłoce

Zmienne pochodzą z miejsca, w którym uruchamiasz Node.js. W terminalu:

// macOS and Linux: for one command
PORT=8080 NODE_ENV=production node app.js

// macOS and Linux: for the rest of the terminal session
export PORT=8080

// Windows PowerShell
$env:PORT = "8080"; node app.js

// Windows cmd.exe
set PORT=8080
node app.js

Platformy hostingowe (Heroku, Render, Vercel, Docker, Kubernetes) mają do tego stronę ustawień albo plik; twój kod czyta je tak samo.

Wszystko jest stringiem

Stąd bierze się większość błędów z process.env. 'false' i '0' to niepuste stringi, więc są truthy:

Naiwne sprawdzenie wypisało debug is ON dla zmiennej ustawionej na false, więc porównuj z dokładnie takim stringiem, jakiego oczekujesz. Przy liczbach Number(process.env.X) zamienia brakującą wartość w NaN, więc ustaw wartość domyślną przed zamianą, jak w pierwszym przykładzie z ??.

NODE_ENV

NODE_ENV to konwencja, a nie funkcja Node.js: Node.js nigdy go nie ustawia. Czytają go biblioteki. Express na przykład ukrywa stack trace na stronach błędów, gdy ma wartość production, a wiele narzędzi pomija sprawdzenia przeznaczone tylko do developmentu.

Wypisało mode: production i verbose logs: false; zmień 'production' na 'development', a druga linia się odwróci. Trzymaj się production, development i test, bo biblioteki sprawdzają dokładnie te słowa.

Pliki .env: --env-file i dotenv

Wpisywanie każdej zmiennej przed node szybko się nudzi. Plik .env trzyma je w folderze projektu, po jednej na linię:

// .env
PORT=8080
DATABASE_URL=postgres://localhost/shop
API_KEY=dev-key-123

Node.js 20.6 i nowsze czytają go przez flagę, bez żadnego pakietu:

node --env-file=.env app.js

W starszych wersjach, albo jeśli wolisz, zainstaluj pakiet dotenv (npm install dotenv) i wczytaj go na samej górze pliku startowego, zanim jakikolwiek kod odczyta process.env:

require('dotenv').config(); // copies .env into process.env

console.log(process.env.PORT); // 8080

Żadne z nich nie nadpisuje zmiennej, która jest już ustawiona w powłoce, więc ustawienia produkcyjne wygrywają z plikiem.

Szybki błąd przy brakujących zmiennych

Brakujący adres bazy danych powinien zatrzymać program przy starcie z jasnym komunikatem, a nie wywrócić go godzinę później przy pierwszym żądaniu:

Wypisało Missing environment variables: API_KEY; dodaj na górze process.env.API_KEY = 'test';, a wypisze się Config OK. W prawdziwym programie po komunikacie wywołaj process.exit(1), bo niezerowy kod wyjścia to sygnał dla skryptu wdrożeniowego albo platformy kontenerowej, że start się nie udał.

Nigdy nie commituj sekretów

Dodaj .env do .gitignore tego samego dnia, w którym go tworzysz. Zamiast niego commituj .env.example z nazwami zmiennych i fałszywymi wartościami, żeby inni wiedzieli, co ustawić. Klucz, który kiedykolwiek trafił do repozytorium, traktuj jako wykradziony i wymień go, nawet jeśli później usuniesz commit.

Najczęściej zadawane pytania

Dlaczego process.env.MY_VAR jest undefined?

Zmienna nie została ustawiona w powłoce, która uruchomiła Node.js, albo ustawiono ją w innym terminalu. Plik .env też nie jest czytany automatycznie: uruchom Node.js z --env-file=.env albo wczytaj go przez dotenv, zanim odczytasz wartość.

Czy mogę zmienić process.env w trakcie działania programu?

Tak. Przypisanie process.env.X = 'value' zmienia zmienną dla bieżącego procesu i każdego procesu potomnego, który uruchomi później, ale nigdy dla powłoki, która uruchomiła Node.js. Node.js zamienia przypisaną wartość na string.

Czy nazwy zmiennych środowiskowych rozróżniają wielkość liter?

W Linuksie i macOS tak: PORT i port to dwie zmienne. W Windows nie. Trzymaj się wielkich liter i podkreślników, a problem nigdy się nie pojawi.

Czy przeglądarka może odczytać process.env?

Nie. Przeglądarki nie mają zmiennych środowiskowych. Narzędzia buildowe takie jak Vite i Next.js kopiują wybrane zmienne do kodu frontendu podczas builda, co oznacza też, że te wartości są publiczne.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

Zacznij