Если вы пишете серверный JavaScript, скорее всего, вам нужно читать информацию из переменных среды. Для обеспечения безопасности рекомендуется делиться конфиденциальной информацией, например токенами доступа, внутри переменных среды. Однако способ чтения переменных среды из JavaScript подвержен ошибкам в некоторых тонкостях, на выяснение которых у вас могут уйти часы. Когда при чтении переменной среды возникает ошибка, вы хотите знать об этом немедленно и не хотите интерпретировать загадочные сообщения об ошибках. Вот где на помощь приходит Env.

Установка Env

Env [1] - это утилита с нулевой зависимостью, разработанная для более безопасного чтения переменных среды и меньшей подверженности ошибкам. Это достигается путем устранения коренных причин ошибок, связанных с переменными среды, в серверном JavaScript. Он работает как в Node.js, так и в Deno и автоматически считывает переменные среды из правильного места в зависимости от используемой среды выполнения.

Чтобы использовать Env в Node.js, установите его с помощью npm:

$ npm install @humanwhocodes/env

А затем импортируйте конструктор Env:

import { Env } from "@humanwhocodes/env";

// or

const { Env } = require("@humanwhocodes/env");

Чтобы использовать Env в Deno, ссылайтесь на него из Skypack:

import { Env } from "https://cdn.skypack.dev/@humanwhocodes/env?dts";

Когда у вас есть конструктор Env, вы можете создать новый экземпляр следующим образом:

const env = new Env();

И теперь вы готовы безопасно читать переменные среды.

Проблема №1: Отсутствуют переменные среды

Первая проблема, которую решает Env, - это то, как работать с отсутствующими переменными среды. Очень часто переменные среды пропадают либо потому, что они были случайно неправильно настроены, либо потому, что они существуют только в некоторых контейнерах, а не во всех. В любом случае вы хотите беспрепятственно обрабатывать отсутствующие переменные среды. В Node.js вы можете сделать что-то вроде этого:

const USERNAME = process.env.USERNAME || "guest";

Цель здесь - использовать переменную среды USERNAME, если она есть, а если нет, по умолчанию "guest". Env упрощает это, чтобы сделать настройки по умолчанию ясными:

const USERNAME = env.get("USERNAME", "guest");

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

const USERNAME = process.env.USERNAME;
if (!USERNAME) {
    throw new Error("Environment variable USERNAME is missing.");
}

Это большой объем кода для простой проверки, и если у вас есть несколько необходимых переменных среды, вам придется повторять этот шаблон для каждой из них. С Env вы можете использовать метод require():

const USERNAME = env.require("USERNAME");

Если в этом примере отсутствует переменная среды USERNAME, выдается сообщение об этом. Вы также можете использовать свойство required аналогичным образом:

const USERNAME = env.required.USERNAME;

Этот синтаксис позволяет избежать ввода строки, но все равно будет выдавать ошибку, если USERNAME отсутствует.

Проблема № 2: Опечатки

Другой тип ошибок, который часто встречается при работе с переменными окружения, - это опечатки. Если вы набираете одно и то же несколько раз, бывает сложно обнаружить опечатки. Например, вы можете ввести что-то вроде этого:

const USERNAME = process.env.USERRNAME;

Лично я потратил часы на отслеживание ошибок, связанных с неправильным вводом имени переменной среды в моем коде. По какой-то причине я правильно набираю имя переменной, но не имя переменной среды. Если вы хотите, чтобы ваши переменные JavaScript имели то же имя, что и некоторые обязательные переменные среды, вы можете использовать деструктуризацию свойства required, чтобы ввести имя только один раз:

const {
    PORT,
    HOST
} = env.required;

Здесь две локальные переменные PORT и HOST создаются из одноименных переменных среды. Если какая-либо переменная среды отсутствует, выдается ошибка.

Проблема № 3: Несоответствие типов

Другой тонкий тип ошибок с переменными среды - несоответствие типов. Например, рассмотрим следующий код Node.js:

const PORT = process.env.PORT || 8080;

Эта строка или что-то подобное встречается во многих приложениях Node.js. В большинстве случаев это не вызывает проблем… но может. Вы можете определить проблему?

Все переменные среды являются строками, поэтому переменная JavaScript PORT является строкой, если переменная среды присутствует, и числом, если нет. Использование аналогичного кода в Deno вызывало ошибку [2], которую мне потребовалось некоторое время, чтобы разобраться. Оказалось, что HTTP-серверу Deno требуется, чтобы порт был номером, поэтому он работал нормально локально, но когда я развернул его в Cloud Run, я получил сообщение об ошибке.

Чтобы решить эту проблему, Env автоматически преобразует все значения по умолчанию в строки:

const PORT = env.get("PORT", 8080);
console.log(typeof PORT === "string");      // always true

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

Проблема # 4: резервные переменные

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

const PORT = process.env.PORT || process.env.HTTP_PORT || 8080;

Вы можете сделать это немного понятнее, используя Env:

const PORT = env.first(["PORT", "HTTP_PORT"], 8080);

Используя этот код, Env возвращает значение из первой найденной переменной среды. Подобно get(), first() позволяет вам передать значение по умолчанию для использования, если ни одна из переменных среды не найдена, и это значение по умолчанию автоматически преобразуется в строку. В качестве дополнительной проверки ошибок, если первый аргумент не является массивом или является массивом только с одним элементом, то выдается ошибка.

Заключение

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

  1. Env
  2. Ошибка serve ():« Uncaught InvalidData »

Изначально этот пост появился в блоге Человек, который кодирует 16 февраля 2021 года. Если вам понравился этот пост, пожалуйста, подумайте о пожертвовании в поддержку моей работы.