mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
f5dd8af7db
* perf(frontend): split heavyweight vendors into manual chunks
Vite's default chunking grouped monaco-editor, the xterm addons,
recharts, @xyflow/react + @dagrejs/dagre, and motion into shared
chunks with the Sencho app code. Any small change in the app would
bust the cache for the heavyweight vendor code, costing repeat
visitors a fresh download.
Add explicit manualChunks for monaco, xterm, charts, flow, and
motion. Each vendor is large enough to justify its own HTTP/2
stream, and grouping them by library keeps their cache key stable
across feature releases.
Also wire rollup-plugin-visualizer behind ANALYZE=true so
`ANALYZE=true npm run build` emits dist/stats.html for ad-hoc
bundle inspection without affecting CI or production builds.
Bump build.chunkSizeWarningLimit from the default 500 KB to 1500 KB
since the monaco chunk is intentionally large; this preserves the
warning's signal value for genuine future regressions.
* fix(frontend): use manualChunks function form for vite 8 typing
Vite 8's OutputOptions overload narrows manualChunks to the
ManualChunksFunction shape, so the object form rejected the chunk
keys with TS2769. Convert to the equivalent function form using
node_modules path matching; same chunk groupings as before.
Also pin rollup-plugin-visualizer to ^6.0.0; 7.x raised the engine
floor to Node 22 and CI runs Node 20, so npm emitted EBADENGINE
warnings. Version 6 supports Node 18+ and exposes the same
visualizer({ filename, gzipSize, brotliSize }) API.
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
import { defineConfig, type PluginOption } from 'vite'
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import { visualizer } from 'rollup-plugin-visualizer'
|
|
import path from 'path'
|
|
import { readFileSync } from 'fs'
|
|
|
|
const rootPkg = JSON.parse(readFileSync(path.resolve(__dirname, '../package.json'), 'utf-8'));
|
|
|
|
// https://vite.dev/config/
|
|
export default defineConfig({
|
|
plugins: [
|
|
react(),
|
|
tailwindcss(),
|
|
// ANALYZE=true npm run build emits dist/stats.html for ad-hoc bundle
|
|
// inspection. Off by default so CI / production builds skip the work.
|
|
process.env.ANALYZE === 'true' && (visualizer({ filename: 'dist/stats.html', gzipSize: true, brotliSize: true }) as PluginOption),
|
|
].filter(Boolean) as PluginOption[],
|
|
define: {
|
|
__APP_VERSION__: JSON.stringify(rootPkg.version),
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
"@": path.resolve(__dirname, "./src"),
|
|
},
|
|
},
|
|
build: {
|
|
// Disable the module-preload polyfill inline script.
|
|
// Vite injects a small inline <script> for module preloading that violates
|
|
// our CSP (script-src 'self' blocks all inline scripts). All modern browsers
|
|
// support <link rel="modulepreload"> natively, so the polyfill is unnecessary.
|
|
modulePreload: { polyfill: false },
|
|
// The monaco chunk is intentionally large (~3 MB minified). Bumping the
|
|
// warning ceiling so the always-firing 500 KB limit does not drown out a
|
|
// genuine future regression.
|
|
chunkSizeWarningLimit: 1500,
|
|
rollupOptions: {
|
|
output: {
|
|
// Group heavyweight vendor libraries into stable chunks so a small
|
|
// app-code change does not bust their cache key. Each chunk is
|
|
// independently large enough to justify its own HTTP/2 stream.
|
|
// Function form (rather than the object form) because Vite 8's
|
|
// OutputOptions overload narrows manualChunks to the function shape.
|
|
manualChunks(id) {
|
|
if (id.includes('node_modules/monaco-editor') || id.includes('node_modules/@monaco-editor/react')) return 'monaco';
|
|
if (id.includes('node_modules/@xterm/')) return 'xterm';
|
|
if (id.includes('node_modules/recharts')) return 'charts';
|
|
if (id.includes('node_modules/@xyflow/react') || id.includes('node_modules/@dagrejs/dagre')) return 'flow';
|
|
if (id.includes('node_modules/motion/')) return 'motion';
|
|
},
|
|
},
|
|
},
|
|
},
|
|
server: {
|
|
proxy: {
|
|
'/api': {
|
|
target: 'http://localhost:1852',
|
|
changeOrigin: true,
|
|
ws: true,
|
|
},
|
|
'/ws': {
|
|
target: 'http://localhost:1852',
|
|
changeOrigin: true,
|
|
ws: true,
|
|
},
|
|
},
|
|
},
|
|
})
|