Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReactRouterV7 with @graphql-codegen/typescript-react-apollo yields error: __vite_ssr_import_3__.useQuery is not a function #975

Open
alicerocheman opened this issue Feb 3, 2025 · 1 comment

Comments

@alicerocheman
Copy link

alicerocheman commented Feb 3, 2025

Which packages are impacted by your issue?

@graphql-codegen/typescript-react-apollo

Describe the bug

Issue

  1. In a ReactRouter V7 (as a framework) with vite and apollo:
  2. Once query hooks have been generated with @graphql-codegen/typescript-react-apollo
  3. the import of Apollo inside the generated file breaks the app with this error:
    TypeError: __vite_ssr_import_[importNb]__.useQuery is not a function

Your Example Website or App

https://stackblitz.com/edit/github-kocgurap-ascqncjf

Steps to Reproduce the Bug or Issue

  1. on the reproduction, run
npm install && npm run dev
  1. the app fails with error "vite_ssr_import_2.useQuery is not a function"

Expected behavior

The npx create-react-router@latest app should run.

Screenshots or Videos

Image

Platform

  • OS: macOS
  • NodeJS: tested on v18.20.3 && v20.16.0
  • graphql version:
    "graphql": "^16.10.0",
    "graphql-tag": "^2.12.6",
  • @graphql-codegen/* version(s):
    "@graphql-codegen/cli": "^5.0.4",
    "@graphql-codegen/near-operation-file-preset": "^3.0.0",
    "@graphql-codegen/typescript": "^4.1.3",
    "@graphql-codegen/typescript-operations": "^4.4.1",
    "@graphql-codegen/typescript-react-apollo": "^4.3.2",

Codegen Config File

import { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
schema: 'schema.graphql',
documents: 'document.graphql',
config: {
gqlImport: 'graphql-tag#gql',
},
generates: {
'types.ts': {
plugins: [
'typescript',
'typescript-operations',
'typescript-react-apollo',
],
},
},
};

export default config;

Additional context

I thought the solution would be to import like this:
import Apollo from '@apollo/client';
instead of the current:
import * as Apollo from '@apollo/client';
but it doesn't seem to work either ('@apollo/client/index has no default export')

Failing test / Solution:

I've looked into this, but I don't know how to solve this

Unrelated issue:

I couldn't use the CodeSandbox link to create a reproduciton repo:

Image
@alicerocheman
Copy link
Author

I have no idea how to fix this issue inside the lib, but I fixed it in my project by running the following script once I've generated my files:

/* eslint-disable no-console */
import * as fs from 'fs';
import * as path from 'path';

const generatedFilesDir = './app/gql';

fs.readdir(generatedFilesDir, (err, files) => {
  if (err) {
    console.error('Error reading directory:', err);
    return;
  }

  files.forEach((file) => {
    if (file.endsWith('.generated.ts')) {
      const filePath = path.join(generatedFilesDir, file);
      fs.readFile(filePath, 'utf8', (err, data) => {
        if (err) {
          console.error('Error reading file:', err);
          return;
        }

        // Remove the old import statement
        const dataWithoutOldImport = data.replace(
          /import \* as Apollo from '@apollo\/client';\s*/g,
          ''
        );

        // Find all Apollo.xxx and collect unique xxx
        const apolloRegex = /Apollo\.(\w+)/g;
        let match;
        const apolloMethods = new Set<string>();
        while ((match = apolloRegex.exec(dataWithoutOldImport)) !== null) {
          apolloMethods.add(match[1]);
        }

        // Create import statements for each unique xxx
        const importStatements = Array.from(apolloMethods)
          .map((method) => {
            if (/^[A-Z]/.test(method)) {
              return `import type { ${method} } from '@apollo/client/index.js';`;
            } else {
              return `import { ${method} } from '@apollo/client/index.js';`;
            }
          })
          .join('\n');

        // Replace Apollo.xxx with xxx
        const updatedData = dataWithoutOldImport.replace(apolloRegex, (match, p1) => p1);

        // Insert import statements at the top of the file
        const finalData = importStatements + '\n' + updatedData;

        fs.writeFile(filePath, finalData, 'utf8', (err) => {
          if (err) {
            console.error('Error writing file:', err);
          } else {
            console.log(`Updated file: ${filePath}`);
          }
        });
      });
    }
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant