modified: vite.config.ts

This commit is contained in:
2025-11-26 16:16:12 +10:00
parent 3797d54bde
commit 0062204f0f
+20 -28
View File
@@ -5,22 +5,25 @@ import { visualizer } from 'rollup-plugin-visualizer';
import path from 'path'; import path from 'path';
function packageNameFromId(id: string) { function packageNameFromId(id: string) {
// Extract the package name from a node_modules path, including scoped packages. const match = id.match(/node_modules[/\\]((?:@[^/\\]+[/\\])?[^/\\]+)/);
const match = id.match(/node_modules\/((?:@[^/]+\/)?[^/]+)/);
return match ? match[1] : null; return match ? match[1] : null;
} }
export default defineConfig({ export default defineConfig({
plugins: [react(), visualizer({ filename: 'dist/stats.html', open: true })], plugins: [
react(),
// keep open: false so it doesn't try to open a browser in Docker/CI
visualizer({ filename: 'dist/stats.html', open: false })
],
resolve: { resolve: {
alias: { alias: {
// Force single copies of react/react-dom to avoid duplicates // ensure only one copy of react/react-dom is used
react: path.resolve(__dirname, 'node_modules/react'), react: path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom') 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
} }
}, },
optimizeDeps: { optimizeDeps: {
// Prebundle React / MUI / Emotion so deps are stable during dev // prebundle to make dev stable
include: [ include: [
'react', 'react',
'react-dom', 'react-dom',
@@ -38,43 +41,32 @@ export default defineConfig({
port: 5173, port: 5173,
}, },
build: { build: {
sourcemap: true, // keep false in container to reduce memory pressure; set true for debugging
sourcemap: false,
outDir: 'dist', outDir: 'dist',
// Use terser (safer wrt TDZ/minifier reordering). Use minify: false for debugging. // esbuild is much lighter than terser: choose esbuild for local/CI builds.
minify: 'terser', // If you want terser for production, switch to 'terser' on a beefy CI runner.
minify: 'esbuild',
chunkSizeWarningLimit: 2000,
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks(id: string) { manualChunks(id: string) {
if (!id) return; if (!id) return;
if (id.includes('node_modules')) { if (id.includes('node_modules')) {
// Put react/react-dom + emotion + styled engine in the same chunk // Put React + MUI + Emotion + styled engine + router into a single vendor chunk
// so initialization order is stable for mui/emotion runtime code. if (/node_modules[/\\](react|react-dom|react-router-dom|@mui|@emotion|@mui[/\\]styled-engine)/.test(id)) {
if (
id.includes('react') ||
id.includes('react-dom') ||
id.includes('react-router-dom') ||
id.includes('@emotion') ||
id.includes('@mui/styled-engine')
) {
return 'react-vendor'; return 'react-vendor';
} }
// MUI splits: specific first, generic later // Keep very large libraries in their own chunk to avoid one giant file
if (id.includes('@mui/icons-material')) return 'mui-icons';
if (id.includes('@mui/material/esm/styles') || id.includes('@mui/material/styles')) return 'mui-styles';
// remaining @mui material code -> mui-core (covers components, utils, etc.)
if (id.includes('@mui/material') || id.includes('@mui/base')) return 'mui-core';
// Keep large libs in their own chunk to avoid a huge 'vendor'
if (id.includes('jszip')) return 'jszip'; if (id.includes('jszip')) return 'jszip';
if (id.includes('papaparse')) return 'papaparse'; if (id.includes('papaparse')) return 'papaparse';
if (id.includes('dexie')) return 'dexie'; if (id.includes('dexie')) return 'dexie';
if (id.includes('@zxing')) return 'zxing'; if (id.includes('@zxing')) return 'zxing';
// Default: create a per-package chunk name so vendor is split up. // Default: small per-package chunk
const pkg = packageNameFromId(id); const pkg = packageNameFromId(id);
if (pkg) { if (pkg) {
// normalize '@' from scoped packages (can't use '/' in filenames)
return `npm.${pkg.replace('/', '__').replace('@', '')}`; return `npm.${pkg.replace('/', '__').replace('@', '')}`;
} }
return 'vendor'; return 'vendor';
@@ -83,7 +75,7 @@ export default defineConfig({
}, },
}, },
commonjsOptions: { commonjsOptions: {
transformMixedEsModules: true transformMixedEsModules: true,
} }
}, },
test: { test: {