You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Apollo GraphQL Codegen在Next.js前端项目中正常工作

Next.js + Apollo Client 类型提示配置问题解决

问题描述

我在使用Next.js,想给前端Apollo React查询加上TypeScript类型提示,但试了各种配置都没用。从src/__generated__/gql导入gql后,查询出现未知错误,悬停gql()时提示:The query argument is unknown! Please regenerate the types。

我的疑问:用Next.js是不是需要特殊配置?想通过《TypeScript with Apollo Client code gendocs》实现gql查询的类型化。另外我的Pothos schema全在pages/api/index.ts里,还不知道怎么拆分到多个文件。

示例查询代码

const CREATED_EVENT_QUERY = gql(`
    query EventById($id: mongoId!) {
        eventById(id: $id) {
            _id
            name
            description
            location{
              coordinates
            }
            date
            eventApplicants{
            name
            userId
            weight
          }
        link
        weights{
          weight
          spotsAvailable{
            name
            userId
          }
        }
        }
    }
`);

// Apollo Query
const { loading, error, data } = useQuery(CREATED_EVENT_QUERY, {
    variables: {
        id: params.id
    }
});

我试过的配置

Apollo官方推荐配置

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

const config: CodegenConfig = {
    schema: 'http://localhost:3000/api',
    documents: ['*.ts'],
    generates: {
        './src/__generated__/': {
            preset: 'client',
            plugins: [],
            presetConfig: {
                gqlTagName: 'gql',
            }
        }
    },
    ignoreNoDocuments: true,
};

export default config;

The Guild的Next.js推荐配置

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

const config: CodegenConfig = {
 // ...
 generates: {
 'path/to/file.ts': {
 plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
 config: {
 reactApolloVersion: 3
 }
 }
 }
}
export default config

两者组合配置

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

const config: CodegenConfig = {
    schema: 'http://localhost:3000/api',
    documents: ['*.ts'],
    generates: {
        'pages/api/index.ts': {
            plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
            config: {
                reactApolloVersion: 3
            }
        }
    },
    ignoreNoDocuments: true,
};

export default config;

解决步骤

1. 修正代码生成核心配置

当前配置存在几个关键问题:

  • 文档路径太宽泛:['*.ts']会匹配所有ts文件,但pages/api下的schema文件无需作为查询文档处理,需指定前端查询路径并排除api目录
  • 生成目标错误:第三个配置将生成文件写入pages/api/index.ts,会覆盖原有schema文件,必须避免;官方client preset生成到src/__generated__目录是正确方向,但需优化配置
  • schema获取方式:本地Pothos schema无需通过HTTP请求获取,直接指向本地文件更可靠

修正后的codegen.ts配置:

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

const config: CodegenConfig = {
  // 直接读取本地Pothos schema文件,无需依赖本地服务启动
  schema: './pages/api/index.ts',
  // 指定前端查询文件路径,排除api目录
  documents: ['src/**/*.{ts,tsx}', 'pages/**/*.{ts,tsx}', '!pages/api/**/*'],
  generates: {
    './src/__generated__/': {
      preset: 'client',
      plugins: [],
      presetConfig: {
        gqlTagName: 'gql',
        // 自动生成类型化useQuery hook
        withHooks: true,
      },
      config: {
        // 映射自定义标量类型到TS类型
        scalars: {
          mongoId: 'string',
        },
      },
    },
  },
  ignoreNoDocuments: true,
};

export default config;

2. 正确使用生成的类型化工具

必须从src/__generated__/gql导入gql和自动生成的类型化hook,无需手动编写查询字符串:

// 正确导入生成的工具
import { useEventByIdQuery } from '../__generated__/gql';

// 直接使用类型化hook,自动校验变量和返回数据类型
const { loading, error, data } = useEventByIdQuery({
  variables: {
    id: params.id,
  },
});

若坚持手动编写查询字符串,也必须使用生成的gql标签,它会自动校验查询语法并提供类型提示。

3. 重新执行代码生成

确保安装所有依赖:

npm install --save-dev @graphql-codegen/cli @graphql-codegen/client-preset

在package.json添加脚本:

{
  "scripts": {
    "codegen": "graphql-codegen",
    "codegen:watch": "graphql-codegen --watch"
  }
}

执行生成命令:

npm run codegen

开发阶段可使用codegen:watch自动监听文件变化并重新生成类型。

4. Pothos schema拆分建议

当前schema集中在一个文件,可按业务类型拆分:

  • 创建pages/api/schemas/Event.ts定义Event类型及相关查询
  • 创建pages/api/schemas/User.ts定义User类型
  • 在pages/api/index.ts导入所有schema文件并合并到Pothos builder

示例拆分后的pages/api/schemas/Event.ts:

import { builder } from '../index';

builder.objectType('Event', {
  fields: (t) => ({
    _id: t.exposeID('_id'),
    name: t.exposeString('name'),
    // 其他字段...
  }),
});

builder.queryField('eventById', (t) =>
  t.field({
    type: 'Event',
    args: {
      id: t.arg({ type: 'mongoId', required: true }),
    },
    resolve: async (_, { id }, { prisma }) => {
      return prisma.event.findUnique({ where: { id } });
    },
  })
);

在pages/api/index.ts导入:

import { builder } from '@pothos/core';
import './schemas/Event';
import './schemas/User';

// 其他配置...

export default builder.toSchema();

内容的提问来源于stack exchange,提问作者Wayne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:40:18