Теперь к делу, вместо того, чтобы просто рассказывать про проблемы, я посидел ночь и напилил confme - решение, которое идет в наш бойлерплейт по NodeJS и может быть полезно комьюнити :)
confme совсем небольшая библиотека, но решает все вышеописанные проблемы, это небольшая обертка вокруг dotenv-defaults и LIVR (для валидации).
Что делает confme?
"confme" загружает конфиг и шаблонизирует его переменными окружения. Для получения переменных окружения библиотека использует dotenv-defaults, то есть вы можете создать файл ".env.defaults" (если захотите) для сохранения значений по умалчанию ваших переменных окружения. Если в конфиге у вас есть плейсхолдеры для которых не существует переменных окружения, то "confme" выбросить исключение.
Также вы можете описать схему конфига и он будет проверен на соотвествие схеме автоматически после шаблонизации.
Как использовать?
const confme = require("confme");
const config = confme( __dirname + "/config.json" );
Файл с конфигурацией:{
"listenPort": "{{PORT}}",
"apiPath": "https://{{DOMAIN}}:{{PORT}}/api/v1",
"staticUrl": "https://{{DOMAIN}}:{{PORT}}/static",
"mainPage": "https://{{DOMAIN}}:{{PORT}}",
"mail": {
"from": "MyApp",
"transport": "SMTP",
"auth": {
"user": "{{SMTP_USER}}",
"pass": "{{SMTP_PASS}}"
}
}
}
DOMAIN, PORT, SMTP_PASS, SMTP_PASS нужно передать в переменных окружения любым способом:Я рекомендую поступать следующим образом:
☑️ Значения по умолчанию для переменных окружения определите в файле ".env.defaults". Они должны подходить для локальной разработки. То есть, разработчику после клонирования репозитория не нужно будет ничего настраивать.
☑️ Если вы деплоите без контейнеров и лямбд, то можете во время деплоймента создавать файл ".env" и переопределять переменные по умолчанию для вашего окружения. Либо можно передавать при запуске, если у вас всего несколько параметров (правда есть риск забыть про них при перезапуске или дебаге продакшена):
DOMAIN=myapp.com PORT=80 node app.js.☑️ Если вы собираете докер контейнер или пакуете лямбды, то просто передавайте переменные окружения способом, который подходит для вашего окружения (для этого всегда есть механизм).
"confme" из коробки поддерживает валидацию конфига при помощи LIVR. Использует LIVR JS и livr-extra-rules (набор дополнительных правил)
Вы можете передать путь к файлу со схемой конфига вторым аргументом:
const confme = require("confme");
const config = confme(
__dirname + "/config.json",
__dirname + "/config-schema.json"
);
Вот пример схемы:{
"listenPort": ["required", "positive_integer"],
"apiPath": ["required", "url"],
"staticUrl": ["required", "url"],
"mainPage": ["required", "url"],
"mail": ["required", {"nested_object": {
"from": ["required", "string"],
"transport": ["required", {"one_of": ["SMTP", "SENDMAIL"] }],
"auth": {"nested_object": {
"user": ["required", "string"],
"pass": ["required", "string"]
}}
}}]
}
Буду рад получить фидбек от читателей канала. Можно в виде звездочек на гитхабе или пишите мне в ТГ. Я - @koorchik