import { defineConfig } from 'vite' import { resolve } from 'path' export default defineConfig({ root: '.', publicDir: false, base: '/static/', build: { outDir: '../static', emptyOutDir: false, sourcemap: false, // Generate manifest.json for Rust backend to resolve hashed filenames manifest: true, rollupOptions: { input: { main: resolve(__dirname, 'src/main.ts'), }, output: { // All files get content hashes for proper cache invalidation entryFileNames: 'js/[name]-[hash].js', chunkFileNames: 'js/[name]-[hash].js', assetFileNames: (assetInfo) => { if (assetInfo.name?.endsWith('.css')) { return 'css/[name]-[hash].css' } return 'assets/[name]-[hash][extname]' }, // Manual chunk splitting for better caching // htmx and Alpine are bundled in the main bundle for immediate availability manualChunks: (id) => { // Map libraries - lazy loaded together if (id.includes('maplibre-gl') || id.includes('h3-js')) { return 'maps' } // Cropper - lazy loaded separately if (id.includes('cropperjs')) { return 'cropper' } }, }, }, minify: 'esbuild', cssMinify: 'lightningcss', }, css: { transformer: 'lightningcss', lightningcss: { targets: { chrome: 110, firefox: 110, safari: 16, }, drafts: { customMedia: true, }, }, }, resolve: { alias: { '@': resolve(__dirname, 'src'), '@styles': resolve(__dirname, 'styles'), }, }, // Ensure dynamic CSS imports work optimizeDeps: { include: ['alpinejs'], }, })