import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; import path from "path"; import runtimeErrorOverlay from "@replit/vite-plugin-runtime-error-modal"; import { metaImagesPlugin } from "./vite-plugin-meta-images"; export default defineConfig({ plugins: [ react(), runtimeErrorOverlay(), tailwindcss(), metaImagesPlugin(), ...(process.env.NODE_ENV !== "production" && process.env.REPL_ID !== undefined ? [ await import("@replit/vite-plugin-cartographer").then((m) => m.cartographer(), ), await import("@replit/vite-plugin-dev-banner").then((m) => m.devBanner(), ), ] : []), ], resolve: { alias: { "@": path.resolve(import.meta.dirname, "client", "src"), "@shared": path.resolve(import.meta.dirname, "shared"), "@assets": path.resolve(import.meta.dirname, "attached_assets"), }, }, css: { postcss: { plugins: [], }, }, root: path.resolve(import.meta.dirname, "client"), build: { outDir: path.resolve(import.meta.dirname, "dist/public"), emptyOutDir: true, rollupOptions: { output: { // Ensure consistent hashing for caching entryFileNames: "assets/[name]-[hash].js", chunkFileNames: "assets/[name]-[hash].js", assetFileNames: (assetInfo) => { const info = assetInfo.name.split("."); const ext = info[info.length - 1]; return `assets/[name]-[hash][extname]`; }, // Manual chunks for better caching manualChunks: { // Vendor libraries that change less frequently vendor: ["react", "react-dom", "wouter"], // UI components ui: ["@radix-ui/react-dialog", "@radix-ui/react-dropdown-menu", "@radix-ui/react-tabs"], // Charts (heavy) charts: ["recharts"], // Export libraries (heavy, loaded on demand) export: ["jspdf", "docx", "html2canvas"], }, }, }, // Generate source maps for production debugging sourcemap: true, }, server: { host: "0.0.0.0", allowedHosts: true, fs: { strict: true, deny: ["**/.*"], }, }, });