Vite использует собственную модель работы с переменными окружения,
основанную на import.meta.env. В отличие от традиционных
сборщиков, где переменные окружения часто подменяются через
process.env, здесь применяется нативная для ESM-концепция,
обеспечивающая статическую подстановку значений на этапе сборки.
Ключевая особенность заключается в том, что переменные становятся частью клиентского бандла только в момент компиляции, а не во время выполнения в браузере.
Любая переменная окружения, которая должна быть доступна в клиентском
коде, обязана иметь префикс VITE_.
Пример:
VITE_API_URL=https://api.example.com
VITE_APP_NAME=MyApp
Без этого префикса переменные игнорируются системой сборки и не
попадают в import.meta.env.
Такое ограничение введено для защиты от случайной утечки секретов в браузерный код.
Система переменных окружения разделяется на два уровня:
Переменные с префиксом VITE_ Доступны в клиентском
коде через import.meta.env.
Все остальные переменные Доступны только в Node.js-окружении (конфигурация, плагины, сервер разработки).
Пример:
VITE_PUBLIC_KEY=abc123
SECRET_KEY=super-secret
В клиентском коде:
console.log(import.meta.env.VITE_PUBLIC_KEY) // доступно
console.log(import.meta.env.SECRET_KEY) // undefined
import.meta.env представляет собой статический объект,
формируемый во время сборки. Он содержит как пользовательские
переменные, так и встроенные системные значения.
Основные встроенные поля:
import.meta.env.MODE — текущий режим
(development, production, кастомные
режимы)import.meta.env.DEV — булево значение, указывающее
режим разработкиimport.meta.env.PROD — булево значение, указывающее
production-сборкуimport.meta.env.BASE_URL — базовый публичный путь
приложенияimport.meta.env.SSR — флаг серверного рендерингаПример использования:
if (import.meta.env.DEV) {
console.log('Режим разработки')
}
fetch(`${import.meta.env.VITE_API_URL}/users`)
Одним из ключевых принципов работы является compile-time replacement. Значения переменных подставляются прямо в код во время сборки.
Исходный код:
const api = import.meta.env.VITE_API_URL
После сборки:
const api = "https://api.example.com"
Это означает отсутствие динамического чтения переменных в runtime, что повышает производительность и позволяет выполнять агрессивные оптимизации.
Vite поддерживает несколько .env файлов, которые
загружаются в строгом порядке приоритетов:
.env — базовые значения.env.local — локальные переопределения (игнорируются в
git).env.[mode] — режим-специфичные значения.env.[mode].local — локальные значения для конкретного
режимаПример структуры:
.env
.env.development
.env.production
.env.local
.env.production.local
Приоритет более специфичных файлов выше общего .env.
Режим определяется через параметр --mode:
vite --mode staging
В этом случае будут загружены:
.env.env.staging.env.staging.localЗначение import.meta.env.MODE будет равно
staging.
Доступ к переменным осуществляется напрямую:
const baseUrl = import.meta.env.VITE_API_URL
В TypeScript требуется расширение интерфейса
ImportMetaEnv, иначе типизация будет ограниченной:
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_NAME: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
Это позволяет получить строгую типизацию и автодополнение в IDE.
Механизм VITE_ не является системой защиты секретов. Это
лишь фильтрация на этапе сборки.
Любая переменная с префиксом VITE_:
Пример неправильного использования:
VITE_ADMIN_PASSWORD=123456
Такие данные считаются публичными после сборки.
В Vite process.env не является основным механизмом
доступа к окружению. Он может присутствовать только в совместимости или
через плагины.
Основной стандарт:
import.meta.env.VITE_API_URL
Проблемы использования process.env:
При серверном рендеринге import.meta.env доступен и на
сервере, но его поведение отличается:
VITE_Пример:
if (import.meta.env.SSR) {
console.log('Серверный рендеринг')
}
Системные переменные играют роль контекста сборки:
Определяет режим работы:
import.meta.env.MODE
import.meta.env.DEV
import.meta.env.PROD
Используются для условной логики:
if (import.meta.env.PROD) {
enableAnalytics()
}
import.meta.env.BASE_URL
Используется для корректной работы приложения при размещении не в корне домена.
Обычно конфигурация строится через комбинацию режимов и
.env файлов:
.env
VITE_API_URL=http://localhost:3000
.env.production
VITE_API_URL=https://api.prod.com
Код остаётся неизменным:
const api = import.meta.env.VITE_API_URL
Поведение меняется только за счёт режима сборки.
Изменение .env файлов требует перезапуска dev-сервера.
Это связано с тем, что переменные читаются на этапе старта процесса и
кешируются.
Переменные import.meta.env могут использоваться не
только в JS, но и в HTML через специальные механизмы Vite, включая
шаблонизацию и плагины.
Пример в index.html:
<script>
window.apiBase = "%VITE_API_URL%"
</script>
Все переменные окружения приходят как строки. Даже если значение выглядит как число или булево, оно требует явного преобразования:
const debug = import.meta.env.VITE_DEBUG === 'true'
const port = Number(import.meta.env.VITE_PORT)
Так как значения подставляются на этапе компиляции, возможен dead code elimination:
if (import.meta.env.DEV) {
console.log('debug')
}
В production этот блок полностью удаляется из финального бандла.
Использование VITE_ и import.meta.env
приводит к следующей архитектурной модели:
Такой подход упрощает мультиокружения (dev, staging, production) без изменения исходного кода.