代码生成工具GraphQLCodeGenerator


代码生成工具GraphQL Code Generator

安装与配置

GraphQL Code Generator(简称codegen)是GraphQL生态中最常用的代码生成工具。它从Schema文件或introspection端点读取类型信息,结合项目中的查询文件,生成目标语言的类型定义、hooks、操作签名等。

核心安装:

npm install -D @graphql-codegen/cli \ @graphql-codegen/typescript \ @graphql-codegen/typescript-operations \ @graphql-codegen/typescript-react-apollo \ @graphql-codegen/fragment-matching ​

配置文件 codegen.ts:

import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { // Schema来源:可以是本地文件、URL、或glob模式 schema: [ './src/schema/**/*.graphql', './node_modules/@apollo/client/link/schema/*.graphql' ], // 查询文件位置 documents: 'src/**/*.{ts,tsx,gql,graphql}', // 生成目标 generates: { // TypeScript类型 './src/__generated__/types.ts': { plugins: [ 'typescript', 'typescript-operations', 'fragment-matching', 'typescript-react-apollo', ], config: { withHooks: true, withMutationFn: true, withSubscriptionHooks: true, enumsAsTypes: true, immutableTypes: true, skipTypename: true, dedupeFragments: true, // 把生成的类型声明为global,避免到处import emitDeclarationOnly: false, } }, // 生成Schema introspection JSON(用于运行时) './src/__generated__/introspection.json': { plugins: ['fragment-matching'], }, }, // 避免生成重复的Fragment类型 hooks: { afterOneFileWrite: ['eslint --fix'] } }; export default config; ​

运行方式

# 单次生成 npx graphql-codegen # 监听模式(开发时推荐) npx graphql-codegen --watch # 强制覆盖 npx graphql-codegen --overwrite ​

监听模式会在Schema文件或查询文件变更时自动重新生成,适合开发阶段。

生成的文件内容

codegen生成的文件通常包含:

// types.ts - 类型定义 export type Maybe<T> = T | null; export type InputMaybe<T> = Maybe<T>; export type User = { __typename?: 'User'; id: string; name: string; email: string; posts: Array<Post>; }; export type Post = { __typename?: 'Post'; id: string; title: string; content: string; author: User; }; // 操作变量和响应类型 export type GetUserQueryVariables = Exact<{ id: string }>; export type GetUserQuery = { user?: { __typename?: 'User'; name: string; posts: Array<{ __typename?: 'Post'; title: string }> }; }; // Apollo生成的hooks export function useGetUserQuery( baseOptions?: ApolloHookOptions<GetUserQuery, GetUserQueryVariables> ) { const options = { ...defaultOptions, ...baseOptions }; return Apollo.useQuery<GetUserQuery, GetUserQueryVariables>(GetUserDocument, options); } export function useGetUserLazyQuery( baseOptions?: ApolloHookOptions<GetUserQuery, GetUserQueryVariables> ) { const options = { ...defaultOptions, ...baseOptions }; return Apollo.useLazyQuery<GetUserQuery, GetUserQueryVariables>(GetUserDocument, options); } // Document nodes(带hash的查询文本,用于持久化查询) export const GetUserDocument = { kind: 'Document', definitions: [...], }; ​

与CI/CD集成

代码生成应该成为构建流水线的一部分:

# GitHub Actions - name: Generate GraphQL types run: npx graphql-codegen - name: Check types run: npx tsc --noEmit # 如果Schema变更导致前端类型不匹配,CI会失败 ​

这确保了每次Schema变更后,前端代码必须同步更新——否则CI会报类型错误。

与Apollo Federation集成

联邦架构中,每个子图有自己的Schema,网关有组合后的Supergraph。Code Generator可以从Supergraph生成客户端类型:

const config: CodegenConfig = { schema: 'http://localhost:4000/graphql', // 网关的Supergraph端点 documents: 'src/**/*.graphql', generates: { './src/__generated__/types.ts': { plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'], } } }; ​

这样前端代码看到的是统一的类型定义,不关心数据来自哪个子图。

Code Generator的价值可以用一句话概括:让Schema成为前后端的单一可信源,不仅体现在API契约上,也体现在TypeScript类型上。

preset 与 monorepo 实践

大型项目通常不止一个客户端(Web、管理后台、小程序)。与其每个项目各写一份 codegen 配置,不如用 preset 统一管理:一份 Schema 源,多个生成目标,生成的类型按项目隔离。

const config: CodegenConfig = { schema: 'schema.graphql', documents: ['web/src/**/*.tsx', 'admin/src/**/*.tsx'], generates: { 'web/src/generated/': { preset: 'client', presetConfig: { fragmentMasking: true }, }, 'admin/src/generated/': { preset: 'client', presetConfig: { fragmentMasking: false }, }, }, }; ​

在 monorepo 里,Schema 往往由服务端包提供,前端包通过 workspace 依赖引用,Schema 变更触发依赖更新,再跑一次 codegen 就能知道影响范围。这比"前端各自保存一份 Schema 副本"可靠得多——副本一定会过期。

常见坑

git 冲突。生成文件如果提交进仓库,多人同时改查询会产生大量冲突。建议生成目录加入忽略列表,用 CI 在构建时生成;如果必须提交,保证 codegen 在本地运行且版本固定。

文档里的操作被重复生成。codegen 会扫描 documents 里所有 graphql 标签,包括测试文件和示例代码,导致重复类型。用 documents 的 glob 精确控制范围,必要时排除测试目录。

Schema 来源不稳定。从远程端点拉 Schema 时,如果端点挂掉或返回不完整,生成会失败或产出残缺类型。本地缓存一份 Schema 快照,远程失败时回退到快照,是稳妥做法。

图:Code Generator工作流

图:Code Generator工作流

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U