diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 553a892b..3fcabff7 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -109,9 +109,23 @@ export default defineConfig({ external: ['node:child_process', 'node:fs', 'node:path', 'node:url'], output: { manualChunks(id) { + // Pin Vite's tiny runtime helpers to their own stable chunk. Otherwise + // Rollup co-locates the `__vitePreload` helper into an arbitrary vendor + // chunk (e.g. `shiki`), and since every dynamic import pulls the helper, + // that whole vendor (here Shiki core + the 629KB oniguruma engine) gets + // dragged into the eager bootstrap graph. + if (id.includes('vite/preload-helper') || id.includes('vite/modulepreload-polyfill')) { + return 'vendor-vite-runtime'; + } if (!id.includes('node_modules')) return undefined; - const match = id.split('node_modules/')[1]; + // Resolve the real package from the LAST `node_modules/` segment. + // bun's isolated install nests packages as + // `node_modules/.bun/@/node_modules//...`, so the first + // `node_modules/` segment is `.bun` — using it collapses every dependency + // (incl. lazy-only ones) into a single giant eager `vendor-.bun` chunk. + const lastNodeModules = id.lastIndexOf('node_modules/'); + const match = id.slice(lastNodeModules + 'node_modules/'.length); if (!match) return undefined; const segments = match.split('/'); @@ -123,7 +137,6 @@ export default defineConfig({ if (packageName === '@opencode-ai/sdk') return 'vendor-opencode-sdk'; if (packageName.includes('remark') || packageName.includes('rehype') || packageName === 'react-markdown') return 'vendor-markdown'; if (packageName === '@base-ui/react' || packageName.startsWith('@base-ui')) return 'vendor-base-ui'; - if (packageName.includes('react-syntax-highlighter') || packageName.includes('highlight.js')) return 'vendor-syntax'; const sanitized = packageName.replace(/^@/, '').replace(/\//g, '-'); return `vendor-${sanitized}`; diff --git a/vite.config.ts b/vite.config.ts index 5f6cb03c..ae9721f4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -33,9 +33,23 @@ export default defineConfig({ external: ['node:child_process', 'node:fs', 'node:path', 'node:url'], output: { manualChunks(id) { + // Pin Vite's tiny runtime helpers to their own stable chunk. Otherwise + // Rollup co-locates the `__vitePreload` helper into an arbitrary vendor + // chunk (e.g. `shiki`), and since every dynamic import pulls the helper, + // that whole vendor (here Shiki core + the 629KB oniguruma engine) gets + // dragged into the eager bootstrap graph. + if (id.includes('vite/preload-helper') || id.includes('vite/modulepreload-polyfill')) { + return 'vendor-vite-runtime' + } if (!id.includes('node_modules')) return undefined - const match = id.split('node_modules/')[1] + // Resolve the real package from the LAST `node_modules/` segment. + // bun's isolated install nests packages as + // `node_modules/.bun/@/node_modules//...`, so the first + // `node_modules/` segment is `.bun` — using it collapses every dependency + // (incl. lazy-only ones) into a single giant eager `vendor-.bun` chunk. + const lastNodeModules = id.lastIndexOf('node_modules/') + const match = id.slice(lastNodeModules + 'node_modules/'.length) if (!match) return undefined const segments = match.split('/') @@ -46,7 +60,6 @@ export default defineConfig({ if (packageName === '@opencode-ai/sdk') return 'vendor-opencode-sdk' if (packageName.includes('remark') || packageName.includes('rehype') || packageName === 'react-markdown') return 'vendor-markdown' if (packageName === '@base-ui/react' || packageName.startsWith('@base-ui')) return 'vendor-base-ui' - if (packageName.includes('react-syntax-highlighter') || packageName.includes('highlight.js')) return 'vendor-syntax' const sanitized = packageName.replace(/^@/, '').replace(/\//g, '-') return `vendor-${sanitized}`