/// import { defineConfig, loadEnv, type Plugin } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' import { visualizer } from 'rollup-plugin-visualizer' // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { const isProduction = mode === 'production' const projectRoot = path.resolve(__dirname) // Load VITE_DOMAIN from .env files (single source of truth for the domain) const envVars = loadEnv(mode, projectRoot, 'VITE_') const domain = envVars.VITE_DOMAIN || 'veza.fr' const backendPort = envVars.VITE_BACKEND_PORT || '18080' return { // Ensure dev server and dep scan use apps/web only (avoid picking up storybook-static when run from monorepo root) root: projectRoot, plugins: [ react(), // Bundle analyzer for production builds (isProduction && visualizer({ filename: 'dist/bundle-analysis.html', open: false, gzipSize: true, brotliSize: true, })) as Plugin, ].filter(Boolean), test: { globals: true, environment: 'jsdom', setupFiles: './src/setupTests.ts', css: true, }, resolve: { alias: { '@': path.resolve(__dirname, './src'), '@components': path.resolve(__dirname, './src/components'), '@features': path.resolve(__dirname, './src/features'), '@services': path.resolve(__dirname, './src/services'), '@hooks': path.resolve(__dirname, './src/hooks'), '@utils': path.resolve(__dirname, './src/utils'), '@types': path.resolve(__dirname, './src/types'), }, }, server: { port: parseInt(process.env.PORT || '5173', 10), host: true, // Allow dev access via the configured domain (VITE_DOMAIN in .env.local) allowedHosts: [domain], // Exclude Storybook build output from watch and fs access so dep scan never touches it watch: { ignored: ['**/storybook-static/**', '**/dist_verification/**'], }, fs: { deny: ['**/storybook-static/**', '**/dist_verification/**'], }, // P2.1: Proxy API and Swagger requests to backend in development // This eliminates CORS issues in dev by making all requests same-origin proxy: { '/api': { target: `http://${domain}:${backendPort}`, changeOrigin: true, secure: false, }, '/swagger': { target: `http://${domain}:${backendPort}`, changeOrigin: true, secure: false, }, }, }, build: { outDir: 'dist_verification', sourcemap: isProduction ? 'hidden' : true, target: 'esnext', minify: 'esbuild', rollupOptions: { output: { manualChunks: (id) => { // Core Vendors if (id.includes('node_modules/react/') || id.includes('node_modules/react-dom/') || id.includes('node_modules/react/jsx-runtime')) { return 'vendor-react'; } if (id.includes('node_modules')) { if (id.includes('react-router')) return 'vendor-router'; if (id.includes('@tanstack')) return 'vendor-tanstack'; if (id.includes('lucide-react')) return 'vendor-icons'; if (id.includes('date-fns')) return 'vendor-utils'; if (id.includes('zod')) return 'vendor-utils'; if (id.includes('framer-motion')) return 'vendor-motion'; if (id.includes('dompurify')) return 'vendor-security'; if (id.includes('axios')) return 'vendor-http'; if (id.includes('i18next')) return 'vendor-i18n'; return 'vendor'; // Default vendor chunk } }, }, }, chunkSizeWarningLimit: 1000, }, // Standard optimization settings usually work best optimizeDeps: { include: ['react', 'react-dom'], // Only scan from app entry; avoid storybook-static (and other build outputs) being picked up as entries entries: ['index.html', 'src/main.tsx'], }, } })