Пошук уроків, статей та іншого контенту
Навчитеся читати змінні середовища, задавати значення за замовчуванням і безпечно працювати з process.env.
Змінні середовища — це значення, які операційна система або середовище запуску передає програмі. Їх часто використовують для налаштування застосунку без зміни коду:
порту сервера;
режиму запуску;
адреси зовнішнього сервісу;
ключів доступу та паролів.
У Node.js змінні середовища доступні через об’єкт process.env.
console.log(process.env.NODE_ENV);Якщо змінна NODE_ENV не задана, результатом буде undefined.
process.envВластивості process.env мають рядкові значення.
const port = process.env.PORT;
console.log(port);
console.log(typeof port);Якщо під час запуску передати PORT=3000, значення port буде рядком "3000", а не числом 3000.
Тому для числових налаштувань потрібно виконати перетворення:
const port = Number(process.env.PORT);
console.log(port);
console.log(typeof port);Не всі змінні обов’язково існують. Якщо змінну не задано, Node.js повертає undefined.
У Linux і macOS змінну можна задати перед командою запуску:
PORT=3000 NODE_ENV=development node app.jsУ Windows PowerShell використовується такий синтаксис:
$env:PORT = "3000"
$env:NODE_ENV = "development"
node app.jsПриклад файлу app.js:
console.log("Порт:", process.env.PORT);
console.log("Режим:", process.env.NODE_ENV);Під час запуску в Linux або macOS програма виведе:
Порт: 3000
Режим: developmentЗмінні, задані таким способом, доступні лише для поточного процесу та його дочірніх процесів.
Застосунку часто потрібне значення, навіть якщо змінну середовища не передали. Для цього можна використати оператор ??:
const port = process.env.PORT ?? "3000";
const mode = process.env.NODE_ENV ?? "development";
console.log({ port, mode });Якщо PORT не задано, port матиме значення "3000".
??Оператор ?? використовує значення праворуч лише тоді, коли значення ліворуч дорівнює null або undefined.
const value = process.env.VALUE ?? "default";Оператор || перевіряє ширше поняття «хибного» значення. Через це він також замінить порожній рядок:
const value = process.env.VALUE || "default";Для змінних середовища зазвичай достатньо ??, оскільки відсутня змінна має значення undefined.
Водночас порожній рядок іноді потрібно вважати неправильним значенням. Це слід перевіряти окремо.
Усі значення з process.env є рядками. Логічні значення також потрібно обробляти явно.
const isProduction = process.env.NODE_ENV === "production";
const port = Number(process.env.PORT ?? "3000");
console.log({ isProduction, port });Не слід перевіряти логічні значення так:
const debug = Boolean(process.env.DEBUG);Рядок "false" є непорожнім, тому Boolean("false") поверне true.
Краще порівнювати рядок із конкретним значенням:
const debug = process.env.DEBUG === "true";Нижче наведено runnable-приклад, який:
читає змінні середовища;
задає значення за замовчуванням;
перетворює порт на число;
перевіряє коректність порту;
не виводить секрет у консоль.
const portText = process.env.PORT ?? "3000";
const nodeEnv = process.env.NODE_ENV ?? "development";
const debug = process.env.DEBUG === "true";
const apiKey = process.env.API_KEY;
const port = Number(portText);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
console.error("Значення PORT має бути цілим числом від 1 до 65535.");
process.exit(1);
}
if (!apiKey) {
console.error("Змінна API_KEY не задана.");
process.exit(1);
}
console.log("Конфігурацію завантажено:");
console.log("Порт:", port);
console.log("Режим:", nodeEnv);
console.log("Налагодження:", debug);
console.log("API ключ отримано:", Boolean(apiKey));Запуск у Linux або macOS:
PORT=8080 NODE_ENV=production DEBUG=false API_KEY=secret-value node app.jsРезультат:
Конфігурацію завантажено:
Порт: 8080
Режим: production
Налагодження: false
API ключ отримано: trueЗверніть увагу: програма виводить лише факт наявності ключа, але не саме значення.
Змінні середовища зручні для секретів, але вони не роблять секрет автоматично безпечним.
Дотримуйтеся таких правил:
не записуйте паролі, токени та ключі безпосередньо в код;
не виводьте секретні значення через console.log;
не додавайте секрети до репозиторію;
перевіряйте обов’язкові змінні під час запуску;
перетворюйте та перевіряйте числові й логічні значення;
не вважайте, що змінна завжди задана.
Небезпечний приклад:
console.log("API key:", process.env.API_KEY);Безпечніший варіант:
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error("API_KEY не задана");
}
console.log("API key завантажено");Навіть повідомлення про помилку не повинно містити значення секрету.
Якщо без змінної застосунок не може працювати, краще завершити запуск із зрозумілою помилкою:
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
console.error("Потрібно задати DATABASE_URL.");
process.exit(1);
}
console.log("Адресу бази даних отримано.");Такий підхід кращий за продовження роботи з undefined, адже помилка виникає одразу під час запуску, а не пізніше в іншій частині програми.
const port = process.env.PORT;
console.log(port + 1);Якщо PORT=3000, результатом буде "30001", бо обидва значення є рядками.
Правильно:
const port = Number(process.env.PORT ?? "3000");
console.log(port + 1);"false"const debug = Boolean(process.env.DEBUG);Для DEBUG=false результат буде true, оскільки "false" — непорожній рядок.
Правильно:
const debug = process.env.DEBUG === "true";const token = process.env.TOKEN;
sendRequest(token);Якщо TOKEN не задано, функція отримає undefined.
Краще перевірити значення до використання:
const token = process.env.TOKEN;
if (!token) {
throw new Error("TOKEN не задана");
}
sendRequest(token);console.log(process.env.DATABASE_PASSWORD);Логи можуть зберігатися, передаватися іншим системам або бути доступними користувачам із доступом до журналів. Не виводьте секрети в консоль.
Змінні середовища читаються через process.env.
Усі значення з process.env є рядками.
Відсутня змінна має значення undefined.
Для значень за замовчуванням зручно використовувати ??.
Числа потрібно перетворювати через Number.
Логічні значення потрібно порівнювати явно, наприклад process.env.DEBUG === "true".
Обов’язкові змінні слід перевіряти під час запуску.
Паролі, токени та ключі не можна виводити в консоль або зберігати безпосередньо в коді.