Как читать переменные среды node в TypeScript?
Если я использую process.env.NODE_ENV
, у меня есть эта ошибка:
Property 'NODE_ENV' does not exist on type 'ProcessEnv'
Я установил @types/node
, но это не помогло.
Как читать переменные среды node в TypeScript?
Если я использую process.env.NODE_ENV
, у меня есть эта ошибка:
Property 'NODE_ENV' does not exist on type 'ProcessEnv'
Я установил @types/node
, но это не помогло.
Нет никакой гарантии того, что (если таковые имеются) переменные среды будут доступны в процессе Node - переменная NODE_ENV
- это просто соглашение, которое было популяризировано Express, а не что-то встроенное в сам Node. Таким образом, не имеет смысла включать его в определения типов. Вместо этого они определяют process.env
следующим образом:
export interface ProcessEnv {
[key: string]: string | undefined
}
Это означает, что process.env
может быть проиндексирован строкой, чтобы вернуть строку (или undefined
, если переменная не установлена). Чтобы исправить ошибку, вам нужно использовать синтаксис индекса:
let env = process.env["NODE_ENV"];
В качестве альтернативы, как указал jcalz в комментариях, если вы используете TypeScript 2.2 или новее, вы можете получить доступ к индексируемым типам, подобным определенным выше, используя синтаксис точки - в этом случае ваш код должен просто работать как есть.
Установив @types/node
в своем проекте, вы можете точно указать TypeScript, какие переменные присутствуют в вашем process.env
:
environment.d.ts
declare global {
namespace NodeJS {
interface ProcessEnv {
GITHUB_AUTH_TOKEN: string;
NODE_ENV: 'development' | 'production';
PORT?: string;
PWD: string;
}
}
}
Этот метод даст вам IntelliSense, а также использует преимущества строковых литералов.
Примечание: приведенный выше фрагмент является дополнением модуля. Файлы, содержащие расширение модулей, должны быть модулями (в отличие от скриптов). Разница между модулями и сценариями заключается в том, что модули имеют как минимум один оператор импорта/экспорта.
Чтобы TypeScript рассматривал ваш файл как модуль, просто добавьте в него одну инструкцию import. Это может быть что угодно. Даже
import * as ts from 'typescript'
подойдет.
просто добавьте перед использованием process.env.NODE_ENV
следующие строки:
declare var process : {
env: {
NODE_ENV: string
}
}
После выполнения с машинописью последней версии:
npm install --save @types/node
Вы можете использовать process.env
напрямую.
console.log(process.env["NODE_ENV"])
вы увидите ожидаемый результат, если вы установили NODE_ENV
.
Для этого вы можете использовать утверждение типа for this
Иногда вы окажетесь в ситуации, когда вы узнаете больше о значение, чем TypeScript. Обычно это происходит, когда вы знаете Тип некоторого объекта может быть более конкретным, чем его текущий тип.
Утверждения типа - это способ сказать компилятору "поверь мне, я знаю, что" Я делаю.' Утверждение типа похоже на приведение типов в других языках, но не выполняет никакой специальной проверки или реструктуризации данных. Не имеет воздействие во время выполнения и используется исключительно компилятором. TypeScript предполагает что вы, программист, выполнили какие-либо специальные проверки, которые вы необходимо.
Пример
const nodeEnv: string = (process.env.NODE_ENV as string);
console.log(nodeEnv);
В качестве альтернативы вы можете найти библиотеку, например env-var, более подходящую для этой конкретной цели -
"решение для загрузки и очистки переменных среды в node.js с правильной типизацией"
.env
# Contents of .env file
AUTHENTICATION_API_URL="http://localhost:4000/login"
GRAPHQL_API_URL="http://localhost:4000/graphql"
.env
в process.env
с помощью dotenv
Мы можем использовать dotenv
для установки переменных process.env
dotenv
от среды. Создайте файл config.ts
в вашем каталоге src/
и заполните его следующим образом:
// Contents of src/config.ts
import {config as configDotenv} from 'dotenv'
import {resolve} from 'path'
switch(process.env.NODE_ENV) {
case "development":
console.log("Environment is 'development'")
configDotenv({
path: resolve(__dirname, "../.env.development")
})
break
case "test":
configDotenv({
path: resolve(__dirname, "../.env.test")
})
break
// Add 'staging' and 'production' cases here as well!
default:
throw new Error(''NODE_ENV' ${process.env.NODE_ENV} is not handled!')
}
Примечание. Этот файл необходимо импортировать в ваш самый верхний файл, скорее всего, в файл src/index.ts с помощью import './config'
(помещается перед всеми остальными импортами).
IProcessEnv
После объединения нескольких методов, описанных выше, мы можем добавить некоторые проверки времени выполнения для проверки IProcessEnv
чтобы гарантировать, что наш объявленный интерфейс IProcessEnv
отражает, какие переменные ENV установлены в наших .env.*
. Содержимое ниже также может находиться в src/config.ts
// More content in config.ts
const throwIfNot = <T, K extends keyof T>(obj: Partial<T>, prop: K, msg?: string): T[K] => {
if(obj[prop] === undefined || obj[prop] === null){
throw new Error(msg || 'Environment is missing variable ${prop}')
}else {
return obj[prop] as T[K]
}
}
// Validate that we have our expected ENV variables defined!
['AUTHENTICATION_API_URL', 'GRAPHQL_API_URL'].forEach(v => {
throwIfNot(process.env, v)
}
export interface IProcessEnv {
AUTHENTICATION_API_URL: string
GRAPHQL_API_URL: string
}
declare global {
namespace NodeJS {
interface ProcessEnv extends IProcessEnv { }
}
}
Это даст нам правильную проверку типа IntelliSense/tslint, а также определенную здравомыслие при развертывании в различных средах.
Обратите внимание, что это также работает для приложения ReactJS (в отличие от серверного приложения NodeJS). Вы можете опустить Шаг (2), потому что это обрабатывается create-react-app
.
Для тех, кто приезжает сюда в поисках ответа для проектов React, имена ваших переменных должны начинаться с REACT_APP_
Узнайте больше здесь: https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables
Вот короткая функция, которая гарантированно извлекает значение process.env в виде строки или в противном случае выдает ошибку.
Для чего-то более мощного (но и большего) другие здесь предложили env-var.
/**
* Returns value stored in environment variable with the given 'name'.
* Throws Error if no such variable or if variable undefined; thus ensuring type-safety.
* @param name - name of variable to fetch from this process environment.
*/
export function env(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error('Missing: process.env['${name}'].');
}
return value;
}
После этого вы сможете написать такой код:
let currentEnvironment: string;
currentEnvironment = env('NODE_ENV');
Если вы хотите использовать .env в TypeScrype, вот простой способ (работает в bash):
1- Создайте файл .env в своем приложении.
2- Настройте свои npm-скрипты в package.json.
3- создайте файл. /dev.sh в каталоге проекта. set -a; source.env; set +a; npm run dev
используйте файл. /dev.sh для запуска вашего проекта.
Таким образом, переменные среды устанавливаются. Если вы установили PORT = 3000 в файле, вы можете получить к нему доступ, используя: process.env.PORT