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

17. Реальная конфигурация

В реальных проектах конфигурация Vite включает десятки настроек: прокси, алиасы, PWA, оптимизации, environment-specific конфиги. Эта глава — финальный урок курса с полным production-ready шаблоном.

vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'
import { visualizer } from 'rollup-plugin-visualizer'
import { VitePWA } from 'vite-plugin-pwa'
import compression from 'vite-plugin-compression'
export default defineConfig(({ command, mode }) => {
// Загружаем env переменные для использования в конфиге
const env = loadEnv(mode, process.cwd(), '')
const isProduction = mode === 'production'
const isDevelopment = mode === 'development'
return {
// Базовый URL (для GitHub Pages: '/my-repo/')
base: env.VITE_BASE_URL || '/',
plugins: [
// React с Fast Refresh
react({
babel: {
plugins: isProduction ? ['babel-plugin-styled-components'] : [],
},
}),
// PWA (Service Worker + Offline Support)
VitePWA({
registerType: 'autoUpdate',
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
},
manifest: {
name: env.VITE_APP_TITLE || 'My App',
short_name: 'App',
theme_color: '#646cff',
},
}),
// Bundle analysis (только при анализе)
mode === 'analyze' && visualizer({
open: true,
gzipSize: true,
brotliSize: true,
filename: 'stats.html',
}),
// Gzip compression (только в production)
isProduction && compression({ algorithm: 'gzip' }),
isProduction && compression({ algorithm: 'brotliCompress', ext: '.br' }),
].filter(Boolean),
// Алиасы
resolve: {
alias: {
'@': resolve(__dirname, './src'),
'@components': resolve(__dirname, './src/components'),
'@hooks': resolve(__dirname, './src/hooks'),
'@utils': resolve(__dirname, './src/utils'),
'@pages': resolve(__dirname, './src/pages'),
'@assets': resolve(__dirname, './src/assets'),
'@store': resolve(__dirname, './src/store'),
'@types': resolve(__dirname, './src/types'),
},
},
// Dev сервер
server: {
port: Number(env.PORT) || 3000,
host: true,
open: isDevelopment,
proxy: {
'/api': {
target: env.VITE_API_TARGET || 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
'/ws': {
target: env.VITE_WS_TARGET || 'ws://localhost:8080',
ws: true,
},
},
hmr: {
overlay: true,
},
},
// Preview сервер
preview: {
port: 8080,
strictPort: true,
},
// Production build
build: {
outDir: 'dist',
sourcemap: !isProduction,
minify: isProduction ? 'terser' : 'esbuild',
target: ['es2020', 'chrome87', 'firefox78', 'safari13'],
chunkSizeWarningLimit: 500,
terserOptions: isProduction ? {
compress: {
drop_console: true,
drop_debugger: true,
},
} : undefined,
rollupOptions: {
output: {
manualChunks: {
'vendor-react': ['react', 'react-dom', 'react-router-dom'],
'vendor-query': ['@tanstack/react-query'],
'vendor-utils': ['lodash-es', 'date-fns'],
},
},
},
},
// CSS конфиг
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/variables" as *;`,
},
},
},
// Глобальные определения
define: {
__APP_VERSION__: JSON.stringify(process.env.npm_package_version),
__BUILD_TIME__: JSON.stringify(new Date().toISOString()),
},
// Оптимизация зависимостей
optimizeDeps: {
include: ['react', 'react-dom', 'react-router-dom'],
exclude: ['@vite/client', '@vite/env'],
},
}
})
.env
VITE_APP_TITLE=My Production App
VITE_BASE_URL=/
# .env.development
VITE_API_TARGET=http://localhost:8080
VITE_WS_TARGET=ws://localhost:8080
PORT=3000
# .env.production
VITE_API_TARGET=https://api.myapp.com
VITE_WS_TARGET=wss://ws.myapp.com
VITE_BASE_URL=/
# .env.staging
VITE_API_TARGET=https://staging-api.myapp.com
VITE_WS_TARGET=wss://staging-ws.myapp.com
{
"scripts": {
"dev": "vite",
"dev:staging": "vite --mode staging",
"build": "tsc --noEmit && vite build",
"build:staging": "vite build --mode staging",
"build:analyze": "vite build --mode analyze",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest run --coverage",
"type-check": "tsc --noEmit"
}
}

Ниже — полный production dashboard: статистика сборки, граф модулей, конфигурация по окружениям: