Перейти к содержимому

Переменные окружения

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

Во время разработки и на этапе сборки переменные, определённые в файле .env или .env.local, добавляются в окружение:

.env.local
API_KEY=19f401ba-e8b0-48c4-8c77-b0ebb26d97fe

По умолчанию каждая переменная окружения неявно доступна внутри приложения через следующие модули:

Начиная с SvelteKit 2.63 можно включить режим явных переменных окружения. В этом случае переменные окружения импортируются из следующих модулей:

Кроме того, модуль $app/environment был переименован в $app/env.

Чтобы включить этот режим, обновите конфигурацию…

svelte.config.js
export default {
kit: {
experimental: {
explicitEnvironmentVariables: true
}
}
};

…и добавьте файл src/env.ts (или src/env.js), который экспортирует объект variables:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
export const variables = defineEnvVars({
// ...
});

Каждое значение в объекте, передаваемом в defineEnvVars, представляет собой объект EnvVarConfig, который определяет параметры соответствующей переменной окружения.

По умолчанию все переменные считаются приватными. Например, вы не захотите раскрывать свой API_KEY:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
export const variables = defineEnvVars({
API_KEY: {}
});

Теперь, когда API_KEY определена, её можно импортировать в код приложения через $app/env/private:

import { API_KEY } from '$app/env/private';

Модуль $app/env/private нельзя импортировать в код, выполняющийся в браузере, поэтому вы не сможете случайно раскрыть свои секретные данные в JavaScript-бандле.

Некоторые переменные полностью безопасно — и даже необходимо — делать доступными в браузере. Для таких переменных можно указать public: true:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
export const variables = defineEnvVars({
GOOGLE_ANALYTICS_ID: {
public: true
}
});

GOOGLE_ANALYTICS_ID теперь можно импортировать из $app/env/public или использовать в шаблоне app.html как %sveltekit.env.GOOGLE_ANALYTICS_ID%:

src/app.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
<script
async
src="https://www.googletagmanager.com/gtag/js?id=%sveltekit.env.GOOGLE_ANALYTICS_ID%"
></script>
<script>
window.dataLayer ??= [];
function gtag(){dataLayer.push(arguments)}
gtag('js', new Date());
gtag('config', '%sveltekit.env.GOOGLE_ANALYTICS_ID%');
</script>
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

Вы можете указать валидатор, совместимый со Standard Schema, например Zod или Valibot, чтобы проверять корректность значения переменной окружения:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
import * as v from 'valibot';
export const variables = defineEnvVars({
GOOGLE_ANALYTICS_ID: {
public: true,
schema: v.pipe(v.string(), v.regex(/G-[A-Z0-9]+/))
}
});

Если значение некорректно, приложение не запустится (или не соберётся). Чтобы отключить проверку только для одного из этих случаев, используйте building из $app/env вместе с валидатором, допускающим отсутствие значения:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
import { building } from '$app/env'
import * as v from 'valibot';
export const variables = defineEnvVars({
SECRET: {
// необязательна при сборке, но обязательна при запуске приложения
schema: building ? v.optional(v.string()) : v.string()
}
});

Вы можете использовать валидаторы, чтобы делать значения необязательными или преобразовывать их (например, превращать строку в булево значение или разбирать JSON) — подробности см. в документации используемой библиотеки валидации.

Если для переменной указано static: true, её значение будет встроено непосредственно в код приложения, что позволяет применять такие оптимизации, как устранение недостижимого кода:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
import * as v from 'valibot';
export const variables = defineEnvVars({
SHOW_DEBUG_OVERLAY: {
public: true,
static: true,
// приводим к true/false
schema: v.pipe(
v.optional(v.string(), ''),
v.transform((str) => str !== '')
)
}
});

Поскольку эта переменная является static, компонент <DebugOverlay>, показанный здесь, будет исключён из JavaScript-бандла, если только SHOW_DEBUG_OVERLAY не будет truthy:

<script>
import { SHOW_DEBUG_OVERLAY } from '$app/env/public';
import DebugOverlay from '#lib/components/DebugOverlay.svelte';
</script>
{#if SHOW_DEBUG_OVERLAY}
<DebugOverlay />
{/if}

Но если переменная установлена перед сборкой приложения…

Окно терминала
SHOW_DEBUG_OVERLAY=true npm run build

…тогда компонент будет включён в бандл и отображён.

Вы можете задокументировать назначение переменной окружения, добавив description:

src/env.ts
import { defineEnvVars } from '@sveltejs/kit/hooks';
export const variables = defineEnvVars({
CACHE_TTL_SECONDS: {
description: 'How long to cache responses, in seconds'
}
});

При наведении курсора на CACHE_TTL_SECONDS в коде вашего приложения отобразится описание.