graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

customFetch configuration option doesn't appear to work with Next.js 15

Open linucks opened this issue 1 year ago • 4 comments

Which packages are impacted by your issue?

@graphql-codegen/cli

Describe the bug

I'm following the documentation to use a custom fetch function, as I need to add authentication for accessing my GraphQL endpoint. I'm using the following codegen.ts file:

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

const config: CodegenConfig = {
  schema: "https://swapi-graphql.netlify.app/.netlify/functions/index",
  documents: ["src/**/*.tsx"],
  customFetch: "myFetch",
  generates: {
    "./src/gql/": {
      preset: "client",
    },
  },
};
export default config;

and have a file called myFetch.ts in the same directory as the codegen.ts file that contains:

const myFetch = async (
  uri: RequestInfo | URL,
  options: RequestInit | undefined
): Promise<Response> => {
  return fetch(uri, {
    ...options,
  });
};

export default myFetch;

Whenever I try and run the command: npx graphql-codegen --config codegen.ts

I get the error:

✔ Parse Configuration
❯ Generate outputs
  ❯ Generate to ./src/gql/
    ⠋ Load GraphQL schemas
    ◼ Load GraphQL documents
    ◼ Generate
node:internal/modules/cjs/loader:1048
  const err = new Error(message);
              ^

Error: Cannot find module 'myFetch'
Require stack:
- /private/tmp/my-app/node_modules/@graphql-tools/url-loader/cjs/index.js
- /private/tmp/my-app/node_modules/@graphql-tools/prisma-loader/cjs/index.js
- /private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/graphql-config.js
- /private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/config.js
- /private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/cli.js
- /private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/bin.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
    at Module._load (node:internal/modules/cjs/loader:901:27)
    at Module.require (node:internal/modules/cjs/loader:1115:19)
    at require (node:internal/modules/helpers:130:18)
    at /private/tmp/my-app/node_modules/@graphql-tools/url-loader/cjs/index.js:15:106 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/private/tmp/my-app/node_modules/@graphql-tools/url-loader/cjs/index.js',
    '/private/tmp/my-app/node_modules/@graphql-tools/prisma-loader/cjs/index.js',
    '/private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/graphql-config.js',
    '/private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/config.js',
    '/private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/cli.js',
    '/private/tmp/my-app/node_modules/@graphql-codegen/cli/cjs/bin.js'
  ]
}

Node.js v20.9.0

This happens regardless of where I put the myFetch.ts file or how I organise the imports.

Your Example Website or App

https://github.com/linucks/gqlcodegen-customfetch

Steps to Reproduce the Bug or Issue

  1. Clone repository and cd into it.
  2. Run npx graphql-codegen --config codegen.ts

Expected behavior

I expected the myFetch.ts file to be found and the function imported and used or all fetches by graphql-codgen.

Screenshots or Videos

No response

Platform

  • OS: macOS 15.0.1
  • NodeJS: v20.9.0
  • @graphql-codegen/* version(s): 5.0.3

Codegen Config File

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

const config: CodegenConfig = { schema: "https://swapi-graphql.netlify.app/.netlify/functions/index", documents: ["src/**/*.tsx"], customFetch: "myFetch", generates: { "./src/gql/": { preset: "client", }, }, }; export default config;

Additional context

No response

linucks avatar Dec 08 '24 16:12 linucks

Hello @linucks,

If you are already using codegen.ts, it could be easier to load your function directly:

import type { CodegenConfig } from "@graphql-codegen/cli";
import myFetch from './myFetch'

const config: CodegenConfig = {
  schema: "https://swapi-graphql.netlify.app/.netlify/functions/index",
  documents: ["src/**/*.tsx"],
  customFetch: myFetch as any, // Note: CodegenConfig's type doesn't have a function as a possible type, so `as any` is required. This can be fixed soon.
  generates: {
    "./src/gql/": {
      preset: "client",
    },
  },
};
export default config;

eddeee888 avatar Dec 23 '24 10:12 eddeee888

Thanks @eddeee888 - that's really helpful. In order to get it to work properly, I needed to add the following to run the command to make sure that tsconfig paths were resolved and the .env file was found (as I needed that to instantiate urql, which I use to set up the GraphQL client to log into the server and get the token): env-cmd graphql-codegen --require tsconfig-paths/register

linucks avatar Jan 08 '25 16:01 linucks

I see, thank you for sharing your approach! 🙌

as I needed that to instantiate urql, which I use to set up the GraphQL client to log into the server and get the token

Are these tokens long-lived? If yes, maybe you could fetch it once into a local, git-ignored .env and loaded it in your custom fetch? Otherwise, every codegen will incur a call to the server (which might or might not be desirable depending on your setup)

eddeee888 avatar Jan 09 '25 10:01 eddeee888

No, they're short-lived (~5 minutes) JWT tokens from Wordpress so need to be refreshed. It works fine using the above approach, but thank you for the suggestion.

linucks avatar Jan 09 '25 18:01 linucks