Головна / Статті

Перевіряйте змінні середовища Node.js за допомогою Zod та TypeScript.

Припиніть читати значення з process.env у всьому коді Node.js. Один файл env.ts, перевірений за допомогою Zod, виявляє відсутні секрети під час запуску та забезпечує додатку конфігурацію у форматі TypeScript із типами.

Видавець: REACTAPP.TOP3 хв читання663 слів

Джерела: https://medium.com/@vetriselvan_11/validating-environment-variables-in-node-js-using-zod-typescript-guide-16f4b6bacaf4

Уявіть собі розгортання у п’ятницю після обіду. Компіляція пройшла успішно, сервер запустився, і всі пішли додому. Через годину користувачі повідомляють, що входи не вдаються. Виявляється, ніхто не встановив значення JWT_SECRET у продакшн-середовищі. Додаток почав працювати без проблем, але зламався лише тоді, коли перше запитання потрапило на код, який потребував відсутнього значення.

Часте використання process.env у всьому кодовому базі підвищує ймовірність таких інцидентів. Далі показано, як замінити цю практику на валідований, типізований модуль конфігурації з використанням Zod та TypeScript.

Звичайний підхід

Більшість кодів на Node.js отримують конфігурацію безпосередньо там, де вона потрібна: порт у одному файлі, адреса бази даних — у іншому.

// Some random controller file
const port = process.env.PORT || 3000;
mongoose.connect(process.env.MONGO_URI);

Це зручно, але має три серйозні проблеми.

  1. Відсутня безпека типів. У TypeScript process.env.PORT має тип string | undefined. Якщо потрібне число, кожен місце виклику мусить його розпарсити вручну.
  2. Тихі збої. Якщо MONGO_URI відсутній, процес не завершується під час запуску. Він зупиняється лише тоді, коли нарешті виконується ця конкретна строка, можливо, через кілька годин після запуску, який здавався успішним.
  3. Відсутнє єдине джерело інформації. Початківець не має списку змінних, необхідних додатку. Їхня єдина можливість — шукати process.env у всьому репозиторії.

Єдиний файл-контролер

Рішенням є припинити змінювати process.env у бізнес-логіці. Один модуль, назвімо його env.ts, читає дані середовища один раз під час запуску, перевіряє їх та експортує об’єкт із суворою типізацією. Усі інші компоненти імпортують цей об’єкт.

Задачу перевірки виконує Zod — бібліотека для верифікації схем, орієнтована на TypeScript.

Встановіть її

npm install zod

Напишіть схему

Розмістіть модуль у src/config/env.ts та детально описайте, яким має бути середовище.

import dotenv from 'dotenv';
import { z } from 'zod';

// Load variables from .env file (if in development)
dotenv.config();

// 1. Define the schema
const envSchema = z.object({
  PORT: z.string().transform(Number).default('3000'),
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  MONGO_URI: z.string(),
  JWT_SECRET: z.string(),
  JWT_EXPIRES_IN: z.string().default('1d'),
});

// 2. Parse the environment against the schema
const _env = envSchema.safeParse(process.env);

// 3. Fail fast if it's invalid
if (!_env.success) {
  console.error('Invalid environment variables:', _env.error.format());
  process.exit(1); // Crash the app immediately!
}

// 4. Export the typed, validated object
export const env = _env.data;

Що робить цей модуль

  • Він визначає необхідні умови. MONGO_URI — це обов’язкова рядкова змінна. PORT також надсилається у вигляді рядка, і функція .transform(Number) перетворює його, при цьому значення за замовчуванням становить 3000. NODE_ENV має бути одним із трьох дозволених значень.
  • Він швидко фіксує помилки. Функція safeParse виконується в момент імпорту файлу, тому його потрібно розмістити на самому початку файлу-вхідного точки, чи то app.ts, чи server.ts. Якщо бракує якоїсь обов’язкової змінної або вона має неправильну форму, результат відображає повідомлення про помилку, у якому точно вказується, що пішло не так, а process.exit(1) зупиняє процес до того, як він почне обробку запитів.
  • Він експортує об’єкт із типами. У разі успіху оброблені дані містять типи, визначені Zod, тож env.PORT вже є числом.

З того моменту будь-який файл може імпортувати env та використовувати його.

Що ви отримуєте

  • Автодоповнення. При введенні env. у вашому редакторі відображається список усіх доступних змінних.
  • Без розкиданих альтернатив. Схеми типу || "default_value" зникають із контролерів, оскільки значення за замовчуванням знаходяться у схемі.
  • Вбудована документація. Схема є точним списком того, що потрібно для роботи додатку, і водночас відповідає на запитання новачків щодо того, що має бути у файлі .env.

Відсутність потрібної таємної змінної тепер зупиняє розгортання протягом кількох секунд під час запуску з чітким повідомленням, замість того щоб проблема проявилась у розлюченому користувачеві через годину.