Связка Vite, React и TypeScript стала стандартом для разработки современных Single Page Applications (SPA). Она обеспечивает мгновенный старт сервера разработки благодаря esbuild и нативным ES-модулям, а также гарантирует строгую типизацию кода. Однако при переходе от базового шаблона к реальному проекту неизбежно возникают задачи тонкой настройки: подключение коротких путей к файлам (алиасов), проксирование сетевых запросов, корректная работа с переменными окружения и разделение клиентских данных и серверных секретов.
Инициализация проекта и базовая структура
Создание нового проекта на Vite занимает несколько секунд. Для связки React и TypeScript используется официальный шаблон react-ts.
Создание шаблона через react-ts
Для генерации структуры выполните команду в терминале:
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
После выполнения команд локальный dev-сервер запустится по умолчанию на порту 5173.
Рекомендуемая файловая структура
Для масштабируемого приложения подходит следующая организация каталогов:
my-app/
├─ public/ # Статические ресурсы (без обработки сборщиком)
├─ src/
│ ├─ assets/ # Изображения, шрифты, глобальные стили
│ ├─ components/ # Переиспользуемые UI-компоненты
│ ├─ pages/ # Компоненты страниц / роуты
│ ├─ lib/ # Утилиты, API-клиенты, хелперы
│ ├─ App.tsx # Корневой компонент
│ ├─ main.tsx # Точка входа в приложение
│ └─ vite-env.d.ts # Декларации типов окружения Vite
├─ .env # Базовые переменные окружения
├─ .env.development # Переменные для режима разработки
├─ .env.production # Переменные для продакшена
├─ .env.local # Локальные переопределения (в .gitignore)
├─ index.html # Базовый HTML-шаблон
├─ package.json # Зависимости и npm-скрипты
├─ tsconfig.json # Основная конфигурация компилятора TypeScript
├─ tsconfig.app.json # Конфигурация TypeScript для исходного кода src
└─ vite.config.ts # Конфигурационный файл Vite
Настройка путей (Path Aliases) в Vite и TypeScript
Относительные импорты вида import { Button } from '../../../components/Button' усложняют чтение кода и рефакторинг. Для решения этой проблемы настраиваются абсолютные пути (псевдонимы или Path Aliases).
Настройка состоит из двух шагов: конфигурации сборщика Vite и конфигурации языкового сервера TypeScript.
Конфигурация resolve.alias в vite.config.ts
Vite требует абсолютные пути файловой системы для сопоставления алиасов. Для формирования таких путей в ESM используется модуль node:url и функции fileURLToPath и URL:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@components': fileURLToPath(new URL('./src/components', import.meta.url)),
},
},
})
Синхронизация с tsconfig.json
Параметр paths в tsconfig.json сообщает компилятору TypeScript, как находить модули во время проверки типов и автодополнения в IDE. Сам по себе TypeScript не переписывает пути в скомпилированном JavaScript — фактическое разрешение выполняет Vite на этапе сборки.
В файле tsconfig.json (или tsconfig.app.json, если проект использует ссылки на проекты) добавьте секцию compilerOptions:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
}
}
Теперь в компонентах можно использовать понятные и независимые от глубины вложенности импорты:
import { Button } from '@components/Button'
import { apiClient } from '@/lib/apiClient'
Локальная разработка: настройка Dev Server и Proxy
При разработке SPA фронтенд обычно работает на одном порту (например, 5173), а бэкенд-сервер — на другом (например, 3000 или 8080). Прямые запросы из браузера к бэкенду приводят к ошибкам CORS (Cross-Origin Resource Sharing).
Решение проблем с CORS через server.proxy
Vite содержит встроенный прокси-сервер на базе Node.js, который перенаправляет запросы к целевому API без ограничений браузерного CORS.
Добавьте блок server в vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
port: 5173,
open: true,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
})
target— адрес локального или удаленного сервера API.changeOrigin: true— меняет заголовокHostзапроса на адрес целевого сервера.rewrite— опциональная функция для модификации URL (например, удаление префикса/api, если бэкенд его не ожидает).
Переменные окружения и безопасность
Vite использует объект import.meta.env для предоставления переменных окружения внутри клиентского кода. Переменные статически заменяются на строковые литералы во время сборки.
Иерархия .env файлов и префикс VITE_
Vite загружает конфигурационные файлы в следующем порядке приоритета (от низшего к высшему):
.env— общие переменные для всех режимов..env.local— локальные переопределения для всех режимов (игнорируются git)..env.[mode]— переменные конкретного режима (.env.developmentили.env.production)..env.[mode].local— локальные переопределения конкретного режима.
Главное правило безопасности: в клиентский бандл попадают только переменные, имена которых начинаются с префикса
VITE_(например,VITE_API_URL).
Пример файла .env.development:
VITE_API_URL=http://localhost:3000/api
VITE_APP_TITLE=My App (Dev)
Пример файла .env.production:
VITE_API_URL=https://api.production-domain.com
VITE_APP_TITLE=My App
Разделение клиентских параметров и серверных секретов
Клиентский код в SPA целиком передается в браузер пользователя. Любой пользователь может открыть вкладку Network или просмотреть исходный код бандла.
- Клиентские параметры (с префиксом
VITE_): публичные URL API, ключи публичной аналитики, идентификаторы проектов (например, публичный ключ Stripe или Sentry DSN). Их попадание в код штатно и безопасно. - Серверные секреты (БЕЗ префикса
VITE_): приватные API-токены, секретные ключи платежных шлюзов, пароли к базам данных. Их категорически запрещено называть с префиксомVITE_и использовать во фронтенд-коде. Такие операции должны выполняться исключительно на промежуточном сервере или в Serverless Functions.
Все файлы с суффиксом .local и файлы, содержащие чувствительные данные разработки, должны быть добавлены в .gitignore:
# .gitignore
.env*.local
.env.local
Типизация import.meta.env через vite-env.d.ts
По умолчанию TypeScript воспринимает пользовательские свойства import.meta.env как any или базовые типы. Чтобы получить автодополнение и строгую проверку типов в IDE, расширьте интерфейс ImportMetaEnv в файле src/vite-env.d.ts:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
Подготовка и проверка production-сборки
Сборка проекта (tsc && vite build)
Стандартный скрипт сборки в package.json выглядит так:
{
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
}
}
Vite использует esbuild для трансформации TypeScript в JavaScript во время разработки и сборки. Esbuild выполняет транспиляцию без проверки типов. Команда tsc -b (или tsc) перед vite build гарантирует, что сборка упадет с ошибкой при наличии нарушений типизации, не допустив дефектный код в релиз.
Дополнительные параметры сборки можно настроить в vite.config.ts:
export default defineConfig({
build: {
outDir: 'dist',
sourcemap: false,
minify: 'esbuild',
},
})
Локальное тестирование собранного бандла (vite preview)
После выполнения npm run build проект компилируется в директорию dist. Чтобы проверить работу приложения в режиме, максимально приближенном к продакшену (без HMR и dev-сервера), используется команда:
npm run preview
Vite запускает легковесный локальный веб-сервер, который раздает статические файлы из папки dist. Это позволяет заранее проверить корректность путей к ассетам, работу роутинга и отсутствие ошибок при инициализации продакшен-бандла.
Часто задаваемые вопросы (FAQ)
1. Почему TypeScript выдает ошибку модуля, если алиас настроен в vite.config.ts?
Vite и TypeScript используют независимые механизмы разрешения модулей. Vite отвечает за бандлинг в браузере, а TypeScript — за проверку типов и автодополнение в редакторе. Если алиас прописан только в vite.config.ts, TypeScript ничего о нем не знает. Необходимо синхронно указывать пути в параметре paths файла tsconfig.json.
2. Попадают ли переменные без префикса VITE_ в клиентский бандл?
Нет. Vite отфильтровывает все переменные окружения, которые не начинаются с VITE_. Они остаются доступными только внутри конфигурационных файлов Node.js (например, в vite.config.ts через вспомогательную функцию loadEnv), но полностью исключаются из клиентского кода.
3. Чем npm run preview отличается от npm run dev?
Команда dev запускает сервер разработки с компиляцией «на лету» (on-demand) и горячей заменой модулей (HMR). Команда preview не компилирует код, а запускает статический HTTP-сервер для раздачи уже готовых, оптимизированных и минифицированных файлов из директории dist.
4. Нужно ли коммитить .env и .env.production в репозиторий?
Базовые шаблоны .env и .env.production, содержащие публичные настройки и адреса эндпоинтов, обычно хранятся в репозитории. Файлы .env.local, .env.development.local и любые конфигурации с приватными секретами должны обязательно находиться в .gitignore.
5. Как работают прокси-настройки server.proxy в продакшен-сборке?
Настройки блока server (включая proxy) работают только во время локальной разработки (npm run dev). В готовом билде (dist) сервер Vite не участвует. Для перенаправления запросов в продакшене необходимо настроить внешний веб-сервер (Nginx, Caddy) или правила хостинг-платформы.
Заключение
Грамотная конфигурация проекта на Vite + React + TypeScript включает четыре ключевых аспекта:
- Синхронизация алиасов между
vite.config.tsиtsconfig.jsonдля чистоты и удобства импортов. - Проксирование API через
server.proxyдля бесшовной локальной разработки без CORS-ошибок. - Строгая изоляция секретов и использование префикса
VITE_исключительно для публичных клиентских параметров. - Валидация типов перед билдом с обязательным вызовом
tscи проверкой результата черезvite preview.
Такой подход защищает приложение от утечек данных, упрощает навигацию по кодовой базе и гарантирует стабильность релизных сборок.



.svg.webp)




