Переменные окружения в приложении Node.js

Hydrock
6 min readJun 15, 2018

--

Переменные окружения или переменные среды (environment variables) — это некие глобальные значения, расположенные на уровне операционной системы, доступные программам, например настройки системы.

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

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

Проблема

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

https://gist.github.com/Hydrock/74151288d3c0863db975827a14ac5c4d

Но мы не можем сохранить такой код в git, иначе мы просто расскажем всему миру наш секретный ключ.

Время переменных окружения

Мы можем хранить секретные данные, настройки сборки и другие данные в переменных окружения. Программа на nodejs имеет к ним доступ.

В nodejs есть глобальный объект process (доступный из любого места программы, как window в браузере), хранящий информацию о текущем процессе. У этого объекта есть свойство env — оно и дает доступ к переменным окружения. Попробуйте запустить node в терминале и выполнить console.log(process.env):

https://gist.github.com/Hydrock/91d18e8c57a9572d07ac12c39de1056c

Мы увидим как в терминал выведется объект со всеми значениями переменных окружения.

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

https://gist.github.com/Hydrock/b5ab3530bb20a2d85d2483bc84603dc3

Мы получаем наш секретный ключ из окружения. Отличный пример 😂.

Еще, вы наверняка использовали или встречали конструкцию node.env.NODE_ENV === ‘production’ для определения режима сборки своего приложения.

Но как же установить эти переменные окружения?

Установка переменных окружения

Главной сложностью, является различие в способах установки переменных окружения в разных операционных системах и разных терминальных оболочках. В основном мы имеем две платформы: Windows и Linux (MacOS). Давайте посмотрим как это сделать в обоих.

Linux, MacOS

Отобразить весь список переменных можно командой printenv.

printenv

Показать конкретную переменную можно так:

echo $[имя переменной без скобок]

Для добавления переменной можно использовать комманду export.

export MYAPIKEY=ndsvn2g86nsb9hsg

Однако нужно помнить, такой способ задает переменную только на текущий сеанс операционной системы.

Так же, можно определить переменные во время запуска программы, в одной строке. Такая переменная будет жить только во время работы программы.

MYAPIKEY=ndsvn2g86nsb9hsg node app.js

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

~/.bash_profile

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

export MYAPIKEY=ndsvn2g86nsb9hsg

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

Windows

Что бы посмотреть список переменных в коммандной строке (Command Prompt) используйте комманду set.

https://gist.github.com/Hydrock/0669b1337825739e7245d856a0e45b07

Вывести значение по имени переменной можно так:

echo %имя переменной%

Добавление новой переменной скрыто за несколькими графическими окнами. Для добавления переменной нажмите Win+R, в открывшемся окне введите sysdm.cpl и нажмите Enter.

В открывшемся окне перейдите на вкладку «Дополнительно» и затем нажмите кнопку «Переменные среды» в правом нижнем углу окна.

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

Создайте пользовательскую переменную, нажав кнопку «Создать» ниже раздела, предназначенного для пользователя. Укажите имя переменной и значение.

Так же можно использовать утилиту setx. Она появилась еще со времен Windows Vista и Windows Server 2008:

setx MYAPIKEY "ndsvn2g86nsb9hsg"

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

Установить временную переменную и запустить процесс node так же возможно:

set MYAPIKEY=ndsvn2g86nsb9hsg && node app.js

Избавляемся от различий

Как вы уже заметили. Запуск node приложения с временными переменными отличается в разных платформах. Что бы решить эту проблему я использую пакет cross-env. Эта небольшая библиотечка позволяет определять временные переменные окружения в одном виде. Определите скрипт в package.json:

https://gist.github.com/Hydrock/1a93153d8b72abd59ad14f2e7f1427a9

Так должно без проблем работать на windows, mac и linux. Конечно хранить никакие ключи тут не нужно.

Все переменные в одном месте

Если вы разрабатываете несколько проектов Node.js на одном компьютере, возможно столкнуться с тем, что у вас есть перекрывающиеся имена переменных окружения. Например для разных приложений могут понадобиться разные ключи MYAPIKEY. Хороший способ исправить это, использовать файл .env, для конфигурации конкретного проекта. Эти файлы позволяют указать различные переменные окружения и их значения.

Просто создайте файл .env в корневом каталоге проекта и добавьте в него все необходимые переменные. В нашем случае:

https://gist.github.com/Hydrock/01a81f9ea8d6689cb377f23ea28ce816

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

Иконки у файлов .env

Далее, необходимо прочитать переменные и добавить их в переменные окружения. Самый распространенный способ — использовать модуль npm, под названием dotenv. Просто установите модуль через npm:

npm install dotenv --save

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

require(‘dotenv’).load();

Пакет dotenv автоматически загрузит файл .env из корневого каталога проекта, и инициализирует значения. Подробнее читайте в документации к пакету. Важной особенностью этого модуля является то что он не перезаписывает уже существующие переменные окружения (хотя и есть способ это сделать) и пропускает их. Есть и другие решения, например env2 и node-env-file.

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

Замечание

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

Заключение

Мы разобрались что такое переменные окружения/среды (environment variables), узнали как создавать временные и постоянные переменные на разных платформах и посмотрели как можно автоматизировать установку значений.

Конечно, эта тема очень большая, и я пробежался по основным возможностям. Но думаю этого достаточно что бы начать с ними работать 😊.

Я надеюсь, вам понравился пост. Если да, похлопайте 👏, чтобы помочь другим найти эту информацию. И не стесняйтесь оставлять комментарии — буду рад любым замечаниям!

--

--