From 87e88743e571853492acdf1ae2e0772544e151ff Mon Sep 17 00:00:00 2001 From: Haoqing Wang <78337154+hqhq1025@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:05:06 +0800 Subject: [PATCH] fix(web): dedupe react and pre-bundle workbox deps in dev (#1211) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Radix Popover crashed with "Invalid hook call" because @radix-ui/react-popover is not linked into web/node_modules and resolves react from the repo root — a different instance than the one app code imports. Two React copies make every hook-using third party component throw on render and unmount the whole tree. The VitePWA dev service worker also pulls its workbox imports only after registration, so Vite re-optimizes deps and force-reloads the page mid-run, which nondeterministically kills whichever e2e test is in flight. --- web/vite.config.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/web/vite.config.ts b/web/vite.config.ts index 2f2e29b6..3217d0f1 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -145,7 +145,24 @@ export default defineConfig({ }) ], base, + optimizeDeps: { + // dev 下 VitePWA 会给每个页面注入 service worker 注册,而 sw.ts 里的 + // workbox 依赖要等 SW 真正注册后才被 Vite 发现,触发一次「optimized + // dependencies changed → reloading」的整页刷新。这个刷新会打断当时 + // 正在跑的 e2e(表现为元素凭空消失)。提前声明即可在启动时一次预构建。 + include: [ + 'workbox-precaching', + 'workbox-routing', + 'workbox-strategies', + 'workbox-expiration' + ] + }, resolve: { + // 单例 React 兜底:workspace 里个别依赖(如 @radix-ui/react-popover) + // 没被链进 web/node_modules,只能从仓库根解析,于是拿到与应用代码 + // 不同的那份 react 实例。两份 React 同时存在会让带 hook 的第三方 + // 组件在渲染时抛 "Invalid hook call",并连累整棵 React 树卸载。 + dedupe: ['react', 'react-dom'], alias: { '@': resolve(__dirname, 'src') }