viteapollocommonjsremix.run

Remix (Vite) unable to import from @apollo/client into .tsx files issue


I have the following root.tsx file:

import { ApolloClient, createHttpLink, InMemoryCache, ApolloProvider } from "@apollo/client";
import { LinksFunction } from "@remix-run/node";
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";
import styleLink from "~/tailwind.css?url";

export function Layout({ children }: { children: React.ReactNode }) {
  const graphQLClient = new ApolloClient({
    ssrMode: true, 
    link: createHttpLink({ 
      uri: 'https://countries.trevorblades.com/graphql', 
      headers: {
        'Access-Control-Allow-Origin': '*', 
      },
    }),
    cache: new InMemoryCache(), 
  });
  
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <ApolloProvider client={graphQLClient}>
          {children}
          <ScrollRestoration />
          <Scripts />
        </ApolloProvider>
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

export const links: LinksFunction = () => [
  { rel: "stylesheet", href: styleLink }
];

And I get the following error:

[vite] Named export 'ApolloProvider' not found. The requested module '@apollo/client' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using: import pkg from '@apollo/client'; const {ApolloClient, createHttpLink, InMemoryCache, ApolloProvider} = pkg;

Now I could import whole package to fix the problem like:

import * as apollo from "@apollo/client";
import { LinksFunction } from "@remix-run/node";
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";
import styleLink from "~/tailwind.css?url";

export function Layout({ children }: { children: React.ReactNode }) {
  const graphQLClient = new apollo.ApolloClient({
    ssrMode: true, 
    link: apollo.createHttpLink({ 
      uri: 'https://countries.trevorblades.com/graphql', 
      headers: {
        'Access-Control-Allow-Origin': '*', 
      },
    }),
    cache: new apollo.InMemoryCache(), 
  });
  
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <apollo.ApolloProvider client={graphQLClient}>
          {children}
          <ScrollRestoration />
          <Scripts />
        </apollo.ApolloProvider>
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

export const links: LinksFunction = () => [
  { rel: "stylesheet", href: styleLink }
];

But then this introduces the following problem:

Imagine you have a different queries.ts file:

import {gql} from "@apollo/client";

export const GET_ALL_NOTES = gql`
    query GetNotes {
        getNotes {
            title,
            content,
            uid,
        }
    }
`;

This works since apollo wont give a CommonJS error when importing in .ts files, but if I were to then import GET_ALL_NOTES into another .tsx file, apollo will then give the CommonJS error for importing gql, and if I were to import the whole package into queries.ts:

import * as apollo from "@apollo/client";

export const GET_ALL_NOTES = apollo.gql`
    query GetNotes {
        getNotes {
            title,
            content,
            uid,
        }
    }
`;

Yields a different type of error:

vite_ssr_import_0.gql is not a function

What can I do to fix this?


Solution

  • Usually, importing from "@apollo/client" works, but in some bundler configurations, you need to import from "@apollo/client/index.js" instead.

    I suggest you give that a try.