import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; function isNodeModule(id) { return id.includes('/node_modules/') || id.includes('\\node_modules\\'); } function manualChunks(id) { if (!isNodeModule(id) || id.endsWith('.css')) { return undefined; } if (id.includes('/@emoji-mart/data/')) { return 'emoji-data'; } if (id.includes('/emoji-mart/')) { return 'emoji-ui'; } if ( id.includes('/@tiptap/') || id.includes('/prosemirror-') || id.includes('/orderedmap/') || id.includes('/rope-sequence/') || id.includes('/w3c-keyname/') ) { return 'vendor-tiptap'; } if (id.includes('/lowlight/') || id.includes('/highlight.js/')) { return 'vendor-syntax'; } if (id.includes('/tippy.js/')) { return 'vendor-tooltip'; } if (id.includes('/framer-motion/')) { return 'vendor-motion'; } if (id.includes('/laravel-echo/') || id.includes('/pusher-js/')) { return 'vendor-realtime'; } return undefined; } function shouldIgnoreRollupWarning(warning) { return warning.code === 'MODULE_LEVEL_DIRECTIVE' && typeof warning.id === 'string' && warning.id.includes('node_modules') && warning.id.includes('framer-motion'); } export default defineConfig({ plugins: [ laravel({ ssr: 'resources/js/ssr.jsx', input: [ 'resources/css/app.css', 'resources/css/nova-grid.css', 'resources/js/app.js', 'resources/scss/nova.scss', 'resources/js/nova.js', 'resources/js/public/home.js', 'resources/js/entry-topbar.jsx', 'resources/js/entry-search.jsx', 'resources/js/entry-masonry-gallery.jsx', 'resources/js/entry-similar-artworks-header.jsx', 'resources/js/entry-pill-carousel.jsx', 'resources/js/upload.jsx', 'resources/js/studio.jsx', 'resources/js/admin.jsx', 'resources/js/dashboard/index.jsx', 'resources/js/artwork.jsx', 'resources/js/Pages/CategoriesPage.jsx', 'resources/js/Pages/News/NewsComments.jsx', 'resources/js/Pages/Community/LatestCommentsPage.jsx', 'resources/js/Pages/Community/CommunityActivityPage.jsx', 'resources/js/Pages/Messages/Index.jsx', 'resources/js/collections.jsx', 'resources/js/feed.jsx', 'resources/js/leaderboard.jsx', 'resources/js/settings.jsx', 'resources/js/moderation.jsx', 'resources/js/forum.jsx', 'resources/js/render-frame.jsx', ], refresh: [ 'resources/views/**', 'routes/**', ], }), ], server: { watch: { ignored: [ '**/node_modules/**', '**/vendor/**', '**/storage/**', '**/public/build/**', '**/.git/**', ], }, }, optimizeDeps: { include: [ 'react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime', '@inertiajs/react', 'framer-motion', ], }, ssr: { // Bundle all npm dependencies into the SSR output — the server has no node_modules. noExternal: true, }, build: { // Prevent heavy vendor chunks (tiptap, framer-motion, syntax, realtime) from being // eagerly preloaded on pages that don't use them (e.g. the homepage). They will still // load on-demand when the dynamic import actually executes. modulePreload: { resolveDependencies: (_filename, deps) => { const heavyVendors = ['vendor-tiptap', 'vendor-syntax', 'vendor-motion', 'vendor-realtime']; return deps.filter(dep => !heavyVendors.some(v => dep.includes(v))); }, }, rollupOptions: { onwarn(warning, warn) { if (shouldIgnoreRollupWarning(warning)) { return; } warn(warning); }, output: { manualChunks, }, }, }, test: { environment: 'jsdom', globals: true, setupFiles: ['resources/js/test/setupTests.js'], include: ['resources/js/**/*.test.{js,jsx}'], }, });