Lerna单仓中React与@tanstack/react-query上下文共享问题求助
以下是针对该场景的具体排查方向和解决方案:
1. 统一组件库与应用的React Query导入方式
确保components包中导入@tanstack/react-query的语法和app包完全一致,比如都使用:
import { useQueryClient } from '@tanstack/react-query'
避免混用CommonJS(require)和ES模块(import)导入,也不要使用自定义别名导入不同的包实例。
2. 验证组件库Rollup配置的外部依赖处理
在components包的rollup.config.js中,必须将react、react-dom、@tanstack/react-query标记为外部依赖,防止打包时将这些依赖嵌入组件库产物,导致重复实例:
export default { // ...其他配置 external: ['react', 'react-dom', '@tanstack/react-query'], output: { format: 'esm', globals: { react: 'React', '@tanstack/react-query': 'ReactQuery' } } }
3. 确认Lerna的依赖Hoisting配置
执行lerna ls --la查看monorepo中@tanstack/react-query的安装位置,确保只存在一份实例。如果使用Lerna v5+,检查lerna.json中的hoist配置:
{ "command": { "bootstrap": { "hoist": true } } }
执行lerna bootstrap --hoist重新安装依赖,强制共享依赖hoist到根目录。
4. 检查Remix的SSR/CSR上下文传递逻辑
Remix作为SSR框架,必须确保QueryClientProvider在服务器端和客户端渲染时都能正确传递上下文:
// app/root.tsx import { QueryClient, QueryClientProvider, dehydrate, Hydrate } from '@tanstack/react-query' import { useLoaderData, Outlet } from '@remix-run/react' export async function loader() { const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000 } } }) // 预查询逻辑(按需添加) return dehydrate(queryClient) } export default function App() { const dehydratedState = useLoaderData() const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000 } } }) return ( <html lang="zh-CN"> <head> {/* 头部内容 */} </head> <body> <QueryClientProvider client={queryClient}> <Hydrate state={dehydratedState}> <Outlet /> </Hydrate> </QueryClientProvider> </body> </html> ) }
重点确保Hydrate组件正确包裹应用内容,客户端能继承服务器端的QueryClient状态。
5. 检查组件库的产物格式配置
在components包的package.json中,明确指定产物类型,确保Remix能正确解析:
{ "name": "@your-org/components", "type": "module", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "peerDependencies": { "react": "^18.2.0", "@tanstack/react-query": "^4.32.0" }, "peerDependenciesMeta": { "react": { "optional": false }, "@tanstack/react-query": { "optional": false } } }
确保Rollup构建出ES模块产物,并通过module字段指向。
6. 测试本地依赖引用方式
如果使用lerna link或npm link进行本地开发,可能存在模块解析异常。尝试在app包的package.json中直接引用组件库源码路径:
{ "dependencies": { "@your-org/components": "file:../components" } }
执行npm install后重新启动应用,排查是否是链接机制导致的上下文丢失。
内容的提问来源于stack exchange,提问作者KiwiCoder

