From 594a13b1f6482b27f9b3059a02b300494f556ab8 Mon Sep 17 00:00:00 2001 From: Yangshun Date: Wed, 21 Oct 2026 16:13:17 +0800 Subject: [PATCH] perf(react): scope prebundles to the consuming environment Keep react-dom/server out of the browser prebundle and react-dom/client out of the Worker prebundle. Preserve the existing SSR prebundle list; disabling the unused Cloudflare SSR optimizer is covered by perf/skip-ssr-prebundle. --- packages/react/src/plugin-pages.ts | 16 ++++--------- packages/react/test/unit/plugin-pages.test.ts | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/react/src/plugin-pages.ts b/packages/react/src/plugin-pages.ts index 919ecc9b3..dcfd36b31 100644 --- a/packages/react/src/plugin-pages.ts +++ b/packages/react/src/plugin-pages.ts @@ -12,15 +12,9 @@ const RENDERER_ID = 'virtual:void-pages-renderer'; const CLIENT_ENTRY_ID = 'virtual:void-pages-client'; const WORKER_ENVIRONMENT_NAME = 'void_worker'; const REACT_DEDUPE = ['react', 'react-dom']; -const REACT_OPTIMIZE_DEPS = [ - 'react', - 'react/jsx-runtime', - 'react/jsx-dev-runtime', - 'react-dom', - 'react-dom/client', - 'react-dom/server', -]; -const WORKER_OPTIMIZE_DEPS = [...REACT_OPTIMIZE_DEPS, 'void/live/client']; +const REACT_OPTIMIZE_DEPS = ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom']; +const CLIENT_OPTIMIZE_DEPS = [...REACT_OPTIMIZE_DEPS, 'react-dom/client']; +const WORKER_OPTIMIZE_DEPS = [...REACT_OPTIMIZE_DEPS, 'react-dom/server', 'void/live/client']; // SSR HTML bypasses transformIndexHtml, so @vitejs/plugin-react cannot inject // its Fast Refresh preamble. Without it, the dev client entry fails to load. @@ -193,11 +187,11 @@ export function pagesPlugin(pagesDir: string, options?: PagesPluginOptions): Plu // Pre-include React entries that are discovered late via dynamic // imports during SPA navigation, avoiding a full-page reload // from Vite's dep optimizer. - include: REACT_OPTIMIZE_DEPS, + include: CLIENT_OPTIMIZE_DEPS, }, ssr: { optimizeDeps: { - include: REACT_OPTIMIZE_DEPS, + include: [...CLIENT_OPTIMIZE_DEPS, 'react-dom/server'], }, }, environments: { diff --git a/packages/react/test/unit/plugin-pages.test.ts b/packages/react/test/unit/plugin-pages.test.ts index f2f945388..5526d7709 100644 --- a/packages/react/test/unit/plugin-pages.test.ts +++ b/packages/react/test/unit/plugin-pages.test.ts @@ -89,6 +89,29 @@ describe('pagesPlugin dev config', () => { }); }); + it('includes only the React entry points needed by each environment', () => { + const config = loadServeConfig() as { + optimizeDeps: { include: Array }; + ssr?: { optimizeDeps?: { include?: Array } }; + environments: { + void_worker: { optimizeDeps: { include: Array } }; + }; + }; + + expect(config.optimizeDeps.include).toContain('react-dom/client'); + expect(config.optimizeDeps.include).not.toContain('react-dom/server'); + expect(config.environments.void_worker.optimizeDeps.include).toContain('react-dom/server'); + expect(config.environments.void_worker.optimizeDeps.include).not.toContain('react-dom/client'); + expect(config.ssr?.optimizeDeps?.include).toEqual([ + 'react', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react-dom', + 'react-dom/client', + 'react-dom/server', + ]); + }); + it('rescans dev renderer loads after adding a page file', async () => { writePage('index.tsx', 'export default function Index() { return

Home

; }\n');