Node.js везде с переменными окружения!

Вы создаете свои приложения Node.js для работы в первую очередь на вашем компьютере. Вы знаете, что важно, чтобы приложения работали везде, где им нужно. Это может быть на компьютерах ваших коллег, внутренних серверах компании, облачных серверах или внутри контейнера (возможно, с использованием Docker). Введите переменные среды.

Переменные среды являются фундаментальной частью разработки с помощью Node.js, позволяя вашему приложению вести себя по-разному в зависимости от среды, в которой вы хотите, чтобы они запускались. Везде, где вашему приложению требуется конфигурация, вы используете переменные среды. И они такие простые, они красивые!

В этом посте вы познакомитесь с созданием и использованием переменных среды, что приведет к созданию приложения Node.js, которое можно запускать где угодно.

Люди часто спрашивают меня, как я решаю, чему учиться и во что вкладывать свое время, а что не стоит забывать. Для меня это начинается с этих двух вопросов (например, с вопроса, почему и когда). Готов поспорить, вы делаете что-то подобное, не так ли?

Почему и когда?

Когда кто-то говорит вам, что что-то важно, и вы должны это использовать, я рекомендую задать два простых вопроса.

  1. Зачем мне его использовать?
  2. Когда мне следует его использовать (или не использовать)?

Почему?

Теперь пришло время спросить меня, почему вам следует использовать переменные среды. Продолжать; Ничего страшного.

Если вы заботитесь о том, чтобы ваше приложение работало на любом компьютере или в облаке (например, в вашей среде), вам следует их использовать. Почему? Потому что они экстернализируют все аспекты вашего приложения, зависящие от среды, и сохраняют ваше приложение инкапсулированным. Теперь вы можете запускать свое приложение где угодно, изменяя переменные среды, не меняя код и не перестраивая его!

Когда?

Хорошо, теперь вы спрашиваете меня, когда вам следует их использовать. Короче говоря, любое место в вашем коде, которое будет меняться в зависимости от среды. Когда вы видите такие ситуации, используйте переменные среды для всего, что вам нужно изменить или настроить.

Вот несколько конкретных примеров распространенных сценариев, когда вам следует рассмотреть возможность использования переменных среды.

  • Какой HTTP-порт слушать
  • В каком пути и в какой папке находятся ваши файлы, которые вы хотите обслуживать
  • Указание на базу данных для разработки, тестирования, тестирования или производства

Другими примерами могут быть URL-адреса ресурсов сервера, CDN для тестирования и производства и даже маркер для маркировки вашего приложения в пользовательском интерфейсе средой, в которой оно находится.

Давайте посмотрим, как можно использовать переменные среды в коде Node.js.

Использование переменных среды

Возможно, вы устанавливаете номер порта для сервера Express. Часто порт в другой среде (например, промежуточная, тестовая, производственная) может потребоваться изменить на основе политик и во избежание конфликтов с другими приложениями. Вам, как разработчику, наплевать на это, да и не нужно. Вот как можно использовать переменную среды в коде для захвата порта.

// server.js
const port = process.env.PORT;
console.log(`Your port is ${port}`);

Давай, попробуй это. Создайте пустую папку с именем env-playground. Затем создайте файл с именем server.js и добавьте к нему приведенный выше код. Теперь, когда вы запускаете node server.js, вы должны увидеть сообщение «Ваш порт не определен».

Вашей переменной среды нет, потому что нам нужно передать их. Давайте рассмотрим несколько способов, как это исправить.

  1. используя командную строку
  2. используя .env файл

Командная строка

Самый простой способ передать порт в ваш код — использовать его из командной строки. Укажите имя переменной, затем знак равенства и значение. Затем запустите приложение Node.js.

PORT=8626 node server.js

Вы увидите порт, отображаемый в сообщении типа «Ваш порт — 8626».

Что это за хрень из 8626? Почему не 4200 или 3000 или что-то более условное? Что ж, я большой поклонник Диснея, и есть персонаж по имени Стич, которого также знали как Эксперимент 626.

Вы можете повторить этот шаблон и добавить другие переменные. Вот пример передачи двух переменных среды.

PORT=8626 NODE_ENV=development node server.js

Следуйте шаблону имени переменной среды, за которым следует знак равенства, за которым следует значение. Это легко сделать, но также слишком легко сделать опечатку. Это приводит к следующему варианту.

Меньше беспорядка с файлом .env

После того, как вы определите несколько из них, следующая мысль, которая может прийти вам в голову, — как с ними справиться, чтобы они не превратились в кошмар обслуживания. Представьте себе несколько из них для подключения к базе данных, портов и ключей. Это плохо масштабируется, когда вы вводите их все в одну строку. И там может быть личная информация, такая как ключи, имена пользователей, пароли и другие секреты.

Конечно, запускать их из командной строки удобно. Но у него есть свои недостатки:

  1. нет хорошего места, чтобы увидеть список переменных
  2. слишком легко сделать ошибку при вводе в командной строке
  3. не идеально запоминать все переменные и их значения
  4. даже со сценариями npm вы все равно должны поддерживать их в актуальном состоянии

Популярным решением, как организовать и поддерживать переменные среды, является использование файла .env. Мне очень нравится эта техника, так как с ее помощью очень легко иметь одно место, где я могу быстро их читать и изменять.

См. также:  Обработан ли обратный вызов циклом событий?

Создайте файл .env в корне вашего приложения и добавьте в него свои переменные и значения.

NODE_ENV=development
PORT=8626
# Set your database/API connection information here
API_KEY=**************************
API_URL=**************************

Запомните свой файл .gitignore

.env file — отличный способ увидеть все переменные среды в одном месте. Только убедитесь, что не поместили их в систему контроля версий. Иначе в вашей истории будут упоминания о ваших секретах!

Создайте .gitignorefile (или отредактируйте существующий, если он у вас уже есть) и добавьте к нему .env, как показано на следующем изображении. Файл .gitignore указывает системе управления версиями игнорировать файлы (или шаблоны файлов), которые вы перечисляете.

Не забудьте добавить .env в файл .gitignore и зафиксировать это изменение, прежде чем добавлять .env . В противном случае вы рискуете зафиксировать раннюю версию вашего .env системы управления версиями.

Вы можете добавить файл в свой .gitignore файл с помощью палитры команд в Visual Studio Code (VS Code). Следуй этим шагам:

  1. Откройте файл, который вы хотите добавить в .gitignore в VS Code.
  2. Откройте палитру команд с помощью CMD + SHIFT + P на Mac или CTRL + SHIFT + P в Windows
  3. Тип ignore
  4. Выберите «Git: Добавить файл в .gitignore из меню».

Это добавит имя текущего открытого файла в .gitignore файл. Если вы не создали .gitignore файл, он создаст его за вас!

Подсветка синтаксиса для вашего файла .env

Если вы используете VS Code, вам нужно добавить расширение dotenv. Это подсвечивает содержимое вашего .env файла подсветкой синтаксиса, и просто старый добрый знак упрощает работу с переменными внутри .env файла.

Вот проблеск файла в VS Code с установленным расширением dotenv.

Чтение файла .env

Прямо сейчас вы, наверное, думаете, что что-то должно искать файл .env, и вы правы!

Вы можете написать свой собственный код, чтобы найти файл, проанализировать его и прочитать в своем приложении Node.js. Или вы можете заглянуть в npm и найти удобный способ прочитать переменные в вашем приложении Node.js одним махом. Скорее всего, вы встретите пакет dotenv на npm, который мне нравится больше всего и который я рекомендую вам использовать. Вы можете установить это так npm install dotenv.

Затем вы можете потребовать этот пакет в своем проекте и использовать его функцию config (config также имеет псевдоним нагрузки, если вы видите это в дикой природе), чтобы искать файл .env, читать переменные, которые вы определили, и сделать их доступными для вашего заявление.

Следуй этим шагам:

  1. создать package.json файл
  2. установить пакет dotenv npm
  3. напишите код, чтобы прочитать .env
  4. запустить код

Создайте файл package.json

Вам понадобится файл package.json для настройки ваших версий, отслеживания ваших зависимостей и хранения ваших сценариев npm. Попробуйте это, выполнив следующую команду

npm init -y

Будет создан файл package.json с заполненными за вас базовыми настройками.

Установить dotenv из npm

Вы хотите прочитать файл .env, и пакет dotenv на npm отлично с этим справляется. Установите пакет dotenv, выполнив следующую команду

npm install dotenv

Это добавит пакет dotenv и его файлы в вашу node_modules папку и создаст в вашем package.json файле запись для dotenv.

Прочтите файл .env

Пришло время прочитать .env файл с небольшим количеством кода. Замените содержимое вашего server.js файла следующим кодом.

// server.js
console.log(`Your port is ${process.env.PORT}`); // undefined
const dotenv = require('dotenv');
dotenv.config();
console.log(`Your port is ${process.env.PORT}`); // 8626

Код отображает начальное значение переменной среды PORT, которое будет неопределенным. Затем ему требуется пакет dotenv, и он выполняет свою config функцию, которая читает .env файл и устанавливает переменные среды. В последней строке кода отображается PORTas 8626.

Запустите код

Теперь запустите код из командной строки, не передавая порт, используя следующую команду

node server.js

Обратите внимание, что сообщения журнала консоли показывают, что порт сначала не определен, а затем — 8626. Пакет dotenv считывает значения и устанавливает их, эффективно делая за вас грязную работу!

Легко находите свои переменные

Теперь, когда у нас есть единое место для создания наших переменных в файле .env, было бы неплохо подумать, как упростить получение всех этих переменных в нашем коде Node.js. Почему? Хороший вопрос! Что ж, вы можете ссылаться на переменные в коде, используя следующий синтаксис:

process.env.YOUR_ENV_VAR_GOES_HERE

Но хотите ли вы делать это везде, где вам это нужно (и они могут понадобиться вам в нескольких местах)? Или вам следует собрать все переменные среды в одном месте? Последнее, конечно! Почему? Если вы будете ссылаться на переменные везде, где они вам нужны, это может затруднить рефакторинг и обслуживание, чем если бы они были в одном месте.

Я рекомендую создать модуль, отвечающий за сбор переменных среды. Это позволяет легко увидеть их все сразу и сопоставить их с удобочитаемыми именами.

Вот два хороших варианта, которые стоит рассмотреть:

  1. установка и экспорт их вручную в модуле
  2. использовать библиотеку для чтения и экспорта в модуль

Оба метода включают создание модуля, но они различаются способом отображения и отображения переменных среды. Давайте подробнее рассмотрим методы и взвесим различия.

Организация вручную

Создайте модуль (пример ниже показывает config.js), в котором вы собираете переменные, сопоставляете им хорошо названные и читаемые свойства и экспортируете их.

Давайте создадим новый модуль в файле с именем config.js. Затем скопируйте и вставьте в файл следующий код.

// config.js
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
  endpoint: process.env.API_URL,
  masterKey: process.env.API_KEY,
  port: process.env.PORT
};

В этом примере показано, как мы можем объединить переменные среды в один файл.

Давайте еще раз изменим server.js, на этот раз, чтобы импортировать модуль config.js и использовать его для доступа к нашим переменным среды. Замените содержимое server.js следующим кодом.

// server.js
const { port } = require('./config');
console.log(`Your port is ${port}`); // 8626

Запустите код, используя node server.js, и вы увидите сообщение «Ваш порт — 8626». Переменные среды считываются кодом dotenv в файле config.js. Ваш server.js файл импортирует модуль в config.js и извлекает переменную порта.

См. также:  Внедрение службы в асинхронный валидатор в Angular

Вы можете импортировать config.js файл туда, где он вам нужен, и использовать деструктурирование, чтобы извлечь то, что вам нужно. Вы только вытащили порт, но вы, конечно, можете вытащить любое из значений, которые экспортируются из модуля.

const { endpoint, masterKey, port } = require(‘./config’);

В чем ценность этой техники?

  1. Это просто
  2. ясность в том, как отображаются все переменные среды
  3. вы можете переименовывать переменные в более удобочитаемые свойства
  4. вы можете добавить другие свойства конфигурации из переменных, не относящихся к среде

Ключевым моментом здесь является то, что целью модуля конфигурации является сбор и предоставление всей конфигурации, независимо от того, откуда она взялась.

Организация с помощью библиотеки

Следствием ручной техники является то, что когда вы добавляете новую переменную среды, вам нужно добавить ее в модуль конфигурации. Например, если вам нужно создать новую переменную, вам нужно будет войти в этот модуль конфигурации и добавить что-то вроде этого

visionApiUrl=process.env.VISION_API_URL

Я не возражаю против этого следствия, так как мне все равно придется просмотреть свой код и использовать новое значение. Но я указываю на это, потому что есть способ собрать их автоматически.

Функция dotenv.config() из пакета dotenv npm будет читать файл .env, назначать переменные process.env и возвращать объект (с именем parsed), содержащий содержимое. в случае неудачи он также выдаст ошибку.

Следующий код считывает файл .env и собирает переменные в объекте envs.

// config.js const dotenv = require('dotenv');
const result = dotenv.config();
if (result.error) {
  throw result.error;
}
const { parsed: envs } = result;
console.log(envs);
module.exports = envs;

Затем вы можете экспортировать этот объект из модуля и снова сделать его легко доступным в своем приложении. Ваш код для доступа к переменным может выглядеть так

const { endpoint, masterKey, port } = require(‘./config’);

Какой вариант использовать? Это вам решать. Но подумайте, хотите ли вы сделать пакет npm dotenv зависимостью времени выполнения или нет. Возможно, есть другие способы получить доступ к переменным среды в более высоких средах (например, в производственной среде), где безопасность имеет первостепенное значение. Вы вообще хотите, чтобы код в вашем приложении узла мог читать такой важный файл? Возможно, вам это понравится, но что, если бы существовал способ прочитать переменные и сделать пакет dotenv зависимостью devDependency в вашем package.json файле?

Я рекомендую вам использовать первый метод, когда вы вручную устанавливаете переменные среды в модуле, например config.js. Это позволяет удалить dotenv как зависимость во время выполнения — при условии, что вы сделаете еще одну вещь: предварительно загрузите переменные среды. Это также позволяет уменьшить ваши зависимости во время выполнения.

Уменьшение ваших зависимостей

У вас много зависимостей от пакетов из npm. Каждый из них — это то, что вы должны учитывать при планировании срока службы и обслуживания вашего приложения. Возможно, вы уже думаете о том, как уменьшить свои зависимости до минимума. Я тоже так делаю.

Пакет dotenv великолепен, но нам не нужно, чтобы он был зависимостью во время выполнения. Пакет dotenv предоставляет возможность предварительно загрузить переменные вне кода. Вы можете загрузить переменные и исключить из нашего кода код, который читает файл .env. Меньше кода — меньше строк, которые можно сломать или сохранить.

Еще не продано? Вы думали о том, как получить доступ к этим переменным среды в облаке? Вы хотите, чтобы ваш код пытался прочитать файл? Я решительно возражаю против этого. Я предпочитаю, чтобы мой код не пытался читать файл, потому что, если я перенесу его в облако, я хочу, чтобы в этих решениях даже не было .env файла.

Как удалить из нашего кода зависимость dotenv во время выполнения, но не потерять уже приобретенное значение? Во-первых, при установке пакета dotenv npm вы можете сохранить его как зависимость от разработчика, как это

npm install dotenv --save-dev

Затем удалите весь код, который использует require на dotenv. Это включает код dotenv.config(), упомянутый ранее в этой статье.

Проблема в том, что раньше вы полагались на dotenv для загрузки переменных среды. Здесь в игру вступает опция предварительной загрузки.

Вы можете запустить приложение узла, используя параметр командной строки — require (-r), чтобы предварительно загрузить dotenv. Следующая команда предварительно загрузит все переменные среды из файла .env с помощью dotenv и сделает их доступными в вашем приложении. Итак, вы удалили из кода все ссылки на dotenv.

node -r dotenv/config server.js

Это полезно, когда вы хотите, чтобы ваше приложение запускалось там, где файл не существует (и, возможно, не должен) существовать, например, в работающем контейнере докеров или на облачном сервере.

Использование сценариев npm

Я настоятельно рекомендую поместить ваши команды в сценарий npm. Это упрощает запуск вместо ввода всех этих флагов. Возможно, вы создадите для него собственный сценарий или воспользуетесь сценарием запуска npm. Вот как может выглядеть сценарий, если вы используете собственный.

scripts: {
  "start_local": "node -r dotenv/config server.js"
}

Затем команда npm run start_local запустит эту команду. Вы, конечно, можете называть сценарий как хотите.

Почему бы не использовать npm start? Хороший вопрос. Вы, конечно, можете это сделать. Я хотел бы зарезервировать npm start на то, как я запускаю его в производстве с нашим контейнером без докера, который может быть просто таким.

scripts: {
  "start": "node server.js"
}

Ключевым моментом здесь является то, что с любым сценарием npm вы запускаете один и тот же код узла! Разница в том, как устанавливаются ваши переменные. Вы выделили конфигурацию из своего приложения.

Отличный инструмент для npm

Как вы запоминаете все свои сценарии npm? Это просто — нет! Я полагаюсь на отличные инструменты для запуска моих сценариев npm. Хотя мне нравится делать вид, что я знаю все имена своих скриптов и что они делают в точности, факт в том, что я предпочел бы иметь инструмент, который показывает мне список, и я могу его выбрать.

См. также:  Веб-аутентификация: файлы cookie или токены

Для этого в выбранный мной редактор кода встроены два фантастических инструмента: VS Code.

  1. наброски сценариев npm
  2. расширение npm

Схема сценариев npm встроена в VS Code и отображается в представлении Explorer. Обратите внимание, что на следующем снимке экрана показаны сценарии npm, которые находятся в моем файле package.json. Если вы не видите этого в своем проекте, обязательно установите для параметра npm.enableScriptExplorer значение true в вашем settings.json для VS Code.

Вы можете щелкнуть правой кнопкой мыши сценарий npm и открыть, запустить или отладить его.

Если вам нравится держать клавиатуру в руках, как это делаю я, то вы можете предпочесть расширение npm для VS Code. После установки расширения npm для VS Code вы можете запускать сценарии npm из палитры команд.

Просто введите CMD + SHIFT + P на Mac или CTRL + SHIFT + P в Windows. Затем начните вводить npm и выберите «npm: Run Script», как показано на изображении ниже.

Затем вам будет представлен список ваших сценариев npm. Отсюда вы можете начать вводить имя того, которое вы хотите, пока то, которое вы хотите, не будет выделено. Или вы можете использовать стрелку, чтобы выбрать нужный сценарий. Затем нажмите ENTER, чтобы запустить его.

Мне это нравится, потому что я держу руки на клавиатуре, что мне кажется более продуктивным, чем переключение между мышью / трекпадом и клавиатурой.

Попробуйте один из них.

Ваш код тот же, где бы он ни работал

Ваше приложение не знает, откуда берутся переменные среды. То, как вы их запускаете, с предварительной загрузкой, — это то, что предоставляет их на вашем локальном компьютере.

Давайте подробнее рассмотрим, почему вы можете захотеть, чтобы ваше приложение не знало о своей конфигурации.

Контейнеры Docker

Представьте, что мы работаем в контейнере Docker. Обычное руководство для контейнеров гласит, что приложения внутри контейнера не должны знать о своей конфигурации. Таким образом, контейнер может работать где угодно, пока контейнер и все, что запускает контейнер, имеют соглашение о том, какие переменные должны быть предоставлены.

Работает в облаке

Когда вы переносите наше приложение в облако, у различных поставщиков облачных услуг также есть способы установить переменные среды. Итак, еще раз, если приложение просто использует переменные, а объект, на котором оно запущено (в данном случае службы облачного провайдера), предоставляет вам способ определить эти переменные, все готово.

  • Во многом это разделение вашего приложения и его конфигурации происходит из-за принципа, известного как 12-факторный. Если вы еще не читали об этом, узнайте больше здесь https://12factor.net.

Поделиться с вашей командой

Как ваши товарищи по команде узнают, какие переменные среды нужно создать для вашего приложения? Стоит ли им искать их в вашем коде? Должны ли они позвонить вам и спросить? Конечно, нет, у вас нет времени навестить каждого разработчика лично!

Когда ваш .env файл не передается в систему управления версиями (чего не должно быть), важно дать всем понять, как должна выглядеть форма этого файла. Я рекомендую вам создать файл с именем .env.example, содержащий переменные, но с поддельными значениями. Этот файл может выглядеть примерно как следующий шаблон.

# .env.example
NODE_ENV=development
PORT=8626
# Set your database connection information here API_KEY=your-core-api-key-goes-here

Ваша группа может скопировать содержимое этого файла в свой собственный файл .env и ввести нужные значения. Совершенно нормально иметь значения, не являющиеся секретами, перечисленными в файле примера. Обратите внимание, что PORT и NODE_ENV в файле .env.example установлены, но не API_KEY. Мудро выбирайте, что вы отправляете в систему управления версиями.

Затем вы можете ссылаться на этот файл в своем README.md, где ваши товарищи по команде могут быстро научиться устанавливать свои собственные значения. Задача решена.

Переменные среды FTW!

Это просто представление о том, как можно использовать переменные среды и о некоторых фантастических инструментах, которые можно использовать с ними. Таким образом, я рекомендую вам использовать переменные среды и выполнить следующие действия:

  1. создать .env файл
  2. игнорируйте это в вашем .gitignore файле
  3. используйте VS Code для редактирования вашего .envfile
  4. установить расширение dotenv для VS Code
  5. установить расширение npm для VS Code
  6. прочтите .envfile с пакетом dotenv npm в качестве зависимости разработчика
  7. используйте опцию предварительной загрузки dotenv, чтобы удалить любые ссылки на нее во время выполнения
  8. используйте сценарии npm для запуска приложения узла
  9. создайте файл шаблона для ваших переменных с именем .env.example

Если вам нравятся шрифт и тема, которые я использую, это Dank Mono и Winter is Coming (синий). Вы можете найти шрифт Dank Mono здесь и установить тему Winter is Coming здесь. Шрифт стоит 40 фунтов стерлингов в последний раз, когда я проверял, а тема бесплатна.

Но ждать? Вы хотите, чтобы на вашем сервере был файл .env? Вы используете Docker или облачный сервер? Это хорошие вопросы, которые стоит задать себе. Подход, который вы изучили здесь, является основой для этого и может работать совместно с другими решениями. Я скоро расскажу об этом в одном из следующих постов, так что следите за обновлениями.

Дополнительные полезные ресурсы по переменным среды

Понравилась статья? Поделиться с друзьями:
IT Шеф
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: