import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { VitePWA } from 'vite-plugin-pwa' import path from 'path' // https://vite.dev/config/ export default defineConfig({ server: { host: true, // Allow external access allowedHosts: [ 'localhost', 'litterscouts.psbailey.uk', '.psbailey.uk', // Allow all subdomains ], }, plugins: [ react(), VitePWA({ registerType: 'autoUpdate', includeAssets: ['vite.svg'], manifest: { name: 'Litter Scouts', short_name: 'Litter Scouts', description: 'Crowdsourced environmental monitoring of Irish coastal areas', theme_color: '#0ea5e9', background_color: '#ffffff', display: 'standalone', icons: [ { src: '/vite.svg', sizes: '192x192', type: 'image/svg+xml', }, { src: '/vite.svg', sizes: '512x512', type: 'image/svg+xml', }, ], }, workbox: { // Cache strategy runtimeCaching: [ { urlPattern: /^https:\/\/api\.*/i, handler: 'NetworkFirst', options: { cacheName: 'api-cache', expiration: { maxEntries: 50, maxAgeSeconds: 60 * 60 * 24, // 24 hours }, cacheableResponse: { statuses: [0, 200], }, }, }, { urlPattern: /^https:\/\/.*\.(?:png|jpg|jpeg|svg|gif|webp)$/, handler: 'CacheFirst', options: { cacheName: 'image-cache', expiration: { maxEntries: 100, maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days }, }, }, { urlPattern: /^https:\/\/tile\.openstreetmap\.org\/.*/i, handler: 'CacheFirst', options: { cacheName: 'map-tiles-cache', expiration: { maxEntries: 500, maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days }, }, }, ], // Don't cache these patterns navigateFallbackDenylist: [/^\/api/], }, }), ], resolve: { alias: { '@': path.resolve(__dirname, './src'), '@/components': path.resolve(__dirname, './src/components'), '@/pages': path.resolve(__dirname, './src/pages'), '@/services': path.resolve(__dirname, './src/services'), '@/hooks': path.resolve(__dirname, './src/hooks'), '@/utils': path.resolve(__dirname, './src/utils'), '@/types': path.resolve(__dirname, './src/types'), }, }, build: { // Optimize bundle size target: 'es2015', minify: 'terser', terserOptions: { compress: { drop_console: true, // Remove console.log in production drop_debugger: true, }, }, rollupOptions: { output: { manualChunks: { // Vendor chunks 'react-vendor': ['react', 'react-dom', 'react-router-dom'], 'clerk-vendor': ['@clerk/clerk-react'], 'query-vendor': ['@tanstack/react-query'], 'map-vendor': ['leaflet', 'react-leaflet', 'leaflet.heat', 'leaflet.markercluster'], 'chart-vendor': ['recharts'], }, }, }, // Increase chunk size warning limit for map libraries chunkSizeWarningLimit: 1000, // Enable CSS code splitting cssCodeSplit: true, // Source maps for production debugging (can be disabled for smaller builds) sourcemap: false, }, // Optimize dependencies optimizeDeps: { include: [ 'react', 'react-dom', 'react-router-dom', '@clerk/clerk-react', '@tanstack/react-query', 'leaflet', 'react-leaflet', ], }, })