T
TanStack2y ago
helpful-purple

Best way to handle monorepo imports?

Let's say I have 3 packages A (app) B (lib) C (ui) Package A imports B and C Package B imports react-query to export and useGraphQL hook (that uses useQuery) Package C imports react-query to export all App.tsx providers so it uses QueryClient, QueryClientProvider I'm having trouble getting Error: No QueryClient set, use QueryClientProvider to set one and I'm guessing this is because of this setup, so I need to change how the packeages are imported (peerDep, devDep ...) But I'm having trouble figuring out how. Anyone with experience on this could point me to the right direction?
3 Replies
fascinating-indigo
fascinating-indigo2y ago
The versions must match everywhere even in useGraphQl
helpful-purple
helpful-purpleOP2y ago
Hey, thanks for the quick answer. They all have "@tanstack/react-query": "^5.12.2" as depencies A is an nextjs using app dir it imports from B which has the useGraphQl hook and imports C at layout.tsx to import the all my providers. Package A
/* eslint-disable import/no-extraneous-dependencies */
import { ExecutionResult } from "graphql";
import { useQuery } from "@tanstack/react-query";
import { TypedDocumentString } from "graphql-types/graphql";
import { HASURA_ENDPOINT } from "lib/utils/config";
import preferenceStorage from "lib/storage/preferenceStorage";

export function useGraphQL<TResult, TVariables>(
document: TypedDocumentString<TResult, TVariables>,
...[variables]: TVariables extends Record<string, never> ? [] : [TVariables]
) {
return useQuery({
queryKey: [
// This logic can be customized as desired
document,
variables,
] as const,
queryFn: async ({ queryKey }) => {
const token = await preferenceStorage.getData("token");
if (token === null) {
throw new Error("Token is null");
}
return fetch(HASURA_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Bearer ": token,
},
body: JSON.stringify({
query: queryKey[0].toString(),
variables: queryKey[1],
}),
}).then((response) => response.json()) as Promise<ExecutionResult<TResult>>;
},
});
}
/* eslint-disable import/no-extraneous-dependencies */
import { ExecutionResult } from "graphql";
import { useQuery } from "@tanstack/react-query";
import { TypedDocumentString } from "graphql-types/graphql";
import { HASURA_ENDPOINT } from "lib/utils/config";
import preferenceStorage from "lib/storage/preferenceStorage";

export function useGraphQL<TResult, TVariables>(
document: TypedDocumentString<TResult, TVariables>,
...[variables]: TVariables extends Record<string, never> ? [] : [TVariables]
) {
return useQuery({
queryKey: [
// This logic can be customized as desired
document,
variables,
] as const,
queryFn: async ({ queryKey }) => {
const token = await preferenceStorage.getData("token");
if (token === null) {
throw new Error("Token is null");
}
return fetch(HASURA_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Bearer ": token,
},
body: JSON.stringify({
query: queryKey[0].toString(),
variables: queryKey[1],
}),
}).then((response) => response.json()) as Promise<ExecutionResult<TResult>>;
},
});
}
Package C ``` "use client"; import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import AuthProvider from './AuthProvider' const queryClient = new QueryClient(); export const Providers = ({ children }: { children: React.ReactNode }) => ( <QueryClientProvider client={queryClient} contextSharing={true}> <AuthProvider> {children} </AuthProvider> </QueryClientProvider> ) ``` layout.tsx ```` export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <Providers> <html lang="pt-br"> <body className={poppins.className}> <main className="flex min-h-full w-full h-full flex-col"> <RenderAuthenticatedPage>{children}</RenderAuthenticatedPage> </main> <Script id="show-banner"> { !function(){var e=window.rudderanalytics=window.rudderanalytics||[];e.methods=["load","page","track","identify","alias","group","ready","reset","getAnonymousId","setAnonymousId","getUserId","getUserTraits","getGroupId","getGroupTraits","startSession","endSession"],e.factory=function(t){return function(){e.push([t].concat(Array.prototype.slice.call(arguments)))}};for(var t=0;t<e.methods.length;t++){var r=e.methods[t];e[r]=e.factory(r)}e.loadJS=function(e,t){var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a)},e.loadJS(), e.load("${RUDDERSTACK_WRITE_KEY}","${RUDDERSTACK_DATA_PLANE_URL}")}(); `} </Script> </body> </html> </Providers> ); } ``` SOLVED: Something was really funky with my turborepo projects.
correct-apricot
correct-apricot15mo ago
I have a similar setup, how did you resolve this issue?

Did you find this page helpful?