Рішення для гнучких та організованих конфігурацій у Node.js
Файли .env традиційно використовуються для управління конфігураціями у Node.js, проте вони мають деякі недоліки:
- Відсутність структури змінних.
- Ризик конфліктів імен.
- «Шум» у глобальному середовищі (process.env).
Щоб вирішити ці проблеми, багато років тому я створив модуль config-in-files. Спершу це було локальне рішення для моїх проєктів, а зараз, в рамках цієї статті, я публікую його як npm-пакет. Можливо він приверне вашу увагу
Усвідомлюю, що існують інші підходи, можливо, сучасніші й досконаліші. Я вже багато років не займають активно аутсорсом і мої знання про популярні бібліотеки могли застаріти. Цей модуль може стати в пригоді розробникам, які шукають простий і ефективний спосіб організації конфігурацій, але остаточну думку я залишаю на розгляд спільноти.
У цій статті я розповім про основні можливості config-in-files, покажу, які проблеми він вирішує, і наведу приклади коду.
Проблеми, які вирішує config-in-files
1. Погана видимість у process.env
Традиційно .env-файли додають змінні до глобального об’єкта process.env. Це призводить до таких проблем:
- Відсутність структури: Усі змінні зберігаються на одному рівні, що ускладнює їх організацію та пошук.
- Конфлікти імен: У деяких проєктах важко слідкувати за назвами змінних.
- Шум у даних: process.env містить як конфігураційні, так і системні змінні.
Рішення:
- Кожна група конфігурацій розбивається на окремі файли.
- config-in-files автоматично збирає дані у структурований об’єкт, де ім’я файлу стає ключем об’єкта.
Приклад:
Файл конфігурації ’project_dir/config/server.js’:
const config = { port: 8080 }; export default config;
Використання
import config from 'config-in-files'; const { port } = await config.server; // 8080
2. Складність роботи із зовнішніми файлами
Деякі типи конфігурацій (наприклад, криптографічні ключі або сертифікати) незручно зберігати у .env. Часто їх вказують лише як шляхи до файлів, що призводить до таких труднощів:
- Жорстка залежність від файлової структури: Будь-яка зміна структури папок оточення потребує редагування шляхів у .env.
- Додаткова логіка в коді: Завантаження та обробка файлів ускладнює основний код програми.
Рішення:
- Модуль виступає посередником між джерелом параметра та його використанням.
- Підтримується логіка завантаження або генерації значень, незалежно від джерела.
- Всі параметри зводяться в єдину структуру, полегшуючи доступ до них.
Приклад:
Файл конфігурації `project_dir/config/auth.js`
import path from 'node:path'; import fs from 'node:fs/promises'; // Отримуємо абсолютний шлях до файлу const envKey = process.env.PRIV_KEY; const projectDir = process.cwd(); const keyPath = path.join(projectDir, envKey); // прочитати ключ у файлі const key = await fs.readFile(keyPath, 'utf-8'); // Створюємо конфігураційний об'єкт const config = { keys: { priv: key } }; // Експортуємо конфігурацію export default config;
Використання
import config from 'config-in-files'; const { priv } = await config.auth.keys; // приватний ключ
3. Оточення Dev, Prod та інші
config-in-files не має вбудованих інструментів для роботи з різними оточеннями, що є певним недоліком. Зізнаюся, я згадав про це вже в процесі написання статті. У найближчий час я можу додати таку функціональність, якщо цей модуль знайде підтримку. Особисто я зараз працюю в іншій сфері, тому ця можливість вже не є для мене критичною. Це може бути реалізовано у вигляді додаткових файлів, наприклад: server.js
, server.dev.js
, server.prod.js
та інші. У цьому підході server.js
буде працювати за замовчуванням, а файли на кшталт server.dev.js
перевизначатимуть співпадаючі ключі з server.js
за умови, що NODE_ENV=dev
.
Наразі можна використовувати змінну середовища NODE_ENV
для керування конфігураціями для розробки, продакшену або інших оточень таким чином:
Приклад:
// Визначаємо середовище на основі NODE_ENV const env = process.env.NODE_ENV; // Вибір порту залежно від середовища const port = env === 'dev' ? 5000 : 8080; // Створюємо конфігураційний об'єкт const config = { port }; // Експортуємо конфігурацію export default config;
Використання
import config from 'config-in-files'; // Отримуємо значення порту з конфігурації const { port } = await config.server; console.log(port); // Якщо NODE_ENV не вказано, використовуватиметься значення за замовчуванням // { port: 8080 } // Якщо NODE_ENV=dev, то значення буде // { port: 5000 }
У підсумку
config-in-files задумувався як легкий і простий інструмент для роботи з конфігураціями у проєктах на Node.js. Це дуже базовий модуль.
Хоча я вже багато років не займаюсь активною розробкою аутсорс-проєктів і не можу з упевненістю сказати, наскільки це рішення актуальне сьогодні, цей модуль не раз допомагав мені впорядкувати конфігурації в проєктах раніше, особливо коли джерелами параметрів була не тільки консоль.
Я публікую його, щоб отримати вашу оцінку ідеї та, за потреби, ви можете використати її у своїх власних проєктах. Ваші відгуки допоможуть удосконалити цей інструмент або дізнатися про його релевантність у сучасних реаліях.
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів