import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' import { VitePWA } from 'vite-plugin-pwa' import { resolve } from 'path' export default defineConfig(({ mode }) => { // Загружаем переменные окружения из корня проекта // Сначала пробуем корневой .env, затем локальный const rootEnv = loadEnv(mode, resolve(process.cwd(), '..'), '') const localEnv = loadEnv(mode, process.cwd(), '') // Объединяем переменные (локальные имеют приоритет) const env = { ...rootEnv, ...localEnv, ...process.env } return { plugins: [ react(), VitePWA({ registerType: 'autoUpdate', includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'favicon.svg'], manifest: { name: 'PlayLife - Статистика и задачи', short_name: 'PlayLife', description: 'Трекер продуктивности и изучения слов', theme_color: '#4f46e5', background_color: '#f3f4f6', display: 'standalone', orientation: 'portrait', start_url: '/', scope: '/', icons: [ { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' }, { src: 'pwa-maskable-192x192.png', sizes: '192x192', type: 'image/png', purpose: 'maskable' }, { src: 'pwa-maskable-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' } ] }, workbox: { // Кэширование статики globPatterns: ['**/*.{js,css,html,ico,png,svg,woff,woff2}'], // Стратегии для API runtimeCaching: [ { // Кэширование данных текущей недели urlPattern: /\/playlife-feed$/, handler: 'NetworkFirst', options: { cacheName: 'api-current-week', expiration: { maxEntries: 1, maxAgeSeconds: 60 * 60 // 1 час }, networkTimeoutSeconds: 10 } }, { // Кэширование полной статистики urlPattern: /\/d2dc349a-0d13-49b2-a8f0-1ab094bfba9b$/, handler: 'NetworkFirst', options: { cacheName: 'api-full-statistics', expiration: { maxEntries: 1, maxAgeSeconds: 60 * 60 // 1 час }, networkTimeoutSeconds: 10 } }, { // Кэширование списка задач urlPattern: /\/api\/tasks$/, handler: 'NetworkFirst', options: { cacheName: 'api-tasks', expiration: { maxEntries: 1, maxAgeSeconds: 60 * 60 // 1 час }, networkTimeoutSeconds: 10 } }, { // Остальные API запросы - только сеть (не кэшировать) urlPattern: /\/api\/.*/, handler: 'NetworkOnly' } ] } }) ], server: { host: '0.0.0.0', port: parseInt(env.VITE_PORT || '3000', 10), proxy: { // Proxy API requests to backend '/api': { target: 'http://localhost:8080', changeOrigin: true, secure: false, }, // Proxy other API endpoints '/playlife-feed': { target: 'http://localhost:8080', changeOrigin: true, secure: false, }, '/d2dc349a-0d13-49b2-a8f0-1ab094bfba9b': { target: 'http://localhost:8080', changeOrigin: true, secure: false, }, '/projects': { target: 'http://localhost:8080', changeOrigin: true, secure: false, }, '/project': { target: 'http://localhost:8080', changeOrigin: true, secure: false, }, } } } })