- 开发工具
【免费下载链接】graphql-code-generator
A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
导读
@graphql-codegen/core是 graphql-code-generator 的核心编排引擎,负责将 schema、documents、plugins、presets 组装成一次完整的代码生成流水线。本文以 packages/graphql-codegen-core/CHANGELOG.md 为主线,梳理从 1.17 到 6.2.0 的演进脉络,重点讲解DocumentTransform 文档变换机制、disableFederationDirectiveAndScalarInjection配置、skipDocumentsValidation验证控制、Node 版本支持策略、ESM/TypeScript 兼容性等核心变更。读完本文,你将掌握 core 包的关键配置项语义、它的内部执行流水线,以及如何在codegen.ts中落地这些能力。
一、core 包在架构中的定位
@graphql-codegen/core不直接参与 CLI 交互,而是提供程序化调用入口。从 packages/graphql-codegen-core/src/index.ts 可以看到它只导出两个东西:
export { codegen } from './codegen.js'; export { executePlugin, ExecutePluginOptions } from './execute-plugin.js';codegen(options: Types.GenerateOptions): Promise<string>—— 一次完整的代码生成流水线,输入 schema + documents + plugins,输出拼接好的代码字符串;executePlugin(...)—— 单个插件的执行器,负责校验插件格式、调用plugin.validate与plugin.plugin。
它的依赖见 packages/graphql-codegen-core/package.json:运行时依赖@graphql-codegen/plugin-helpers(类型与工具函数)、@graphql-tools/schema(schema 合并)、@graphql-tools/utils(文档校验),并以graphql为 peerDependency。这正是 6.2.0 中依赖更新的落点。
一句话理解:CLI 负责读配置、加载插件/预设,core 负责把一切"编排"成字符串输出。
二、最新版本(6.x)核心变更
2.1 6.2.0:依赖升级与 GraphQL 17 支持
- 依赖
@graphql-tools/utils从^11.0.0升到^11.2.0; - peerDependencies 中的
graphql范围扩展为^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0,新增 GraphQL 17 支持; - 同时联动更新
@graphql-codegen/plugin-helpers@7.1.0。
从 packages/graphql-codegen-core/package.json 的exports字段可以看到,该包同时提供 CJS(require→dist/cjs/index.js)与 ESM(import→dist/esm/index.js)双入口,这与 2.1.0 引入的 ESM 支持一脉相承。
2.2 6.1.0:新增disableFederationDirectiveAndScalarInjection(Federation v2 友好)
这是 6.1.0 唯一的功能变更:新增disableFederationDirectiveAndScalarInjection配置,用于更好地支持 Federation v2。
其底层行为在 packages/graphql-codegen-core/src/codegen.ts 中清晰可见:
const federationInConfig: boolean = pickFlag('federation', options.config); const disableFederationDirectiveAndScalarInjection: boolean = pickFlag( 'disableFederationDirectiveAndScalarInjection', options.config, ); const isFederation = prioritize(federationInConfig, false); if ( isFederation && !disableFederationDirectiveAndScalarInjection && !hasFederationSpec(options.schemaAst || options.schema) ) { additionalTypeDefs.push(federationSpec); }含义拆解:
- 当
federation: true且 schema 中尚未包含 Federation 指令(@key、@requires、@provides、@external,判断逻辑见 packages/graphql-codegen-core/src/utils.ts)时,core 会自动注入 legacy Federation v1 的指令与标量定义(如@key、@external、_FieldSet); - 在 Federation v2 场景下,这些 v1 指令可能与子图 schema 冲突或造成冗余注入,因此将
disableFederationDirectiveAndScalarInjection: true可显式关闭自动注入。
用法示例(codegen.ts):
import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { schema: './schema.graphql', generates: { './src/types.ts': { plugins: ['typescript', 'typescript-operations'], config: { federation: true, disableFederationDirectiveAndScalarInjection: true, // 关闭 v1 指令自动注入 }, }, }, }; export default config;2.3 6.0.0:移除 Node 20 支持
6.0.0 的破坏性变更只有一条:Drop Node 20 support,并同步升级@graphql-codegen/plugin-helpers@7.0.0。这与 5.0.0(Drop Node 18)、4.0.0(要求 Node ≥ 16、移除 Node 14)、3.0.0(移除 Node 12)、2.0.0(移除 Node 10)一脉相承——core 包持续跟进 LTS 策略,具体以 packages/graphql-codegen-core/package.json 中engines: { "node": ">=16" }为准。
需要说明:该文档记录的 Node 支持策略为"逐步放弃旧版本、跟随当时活跃 LTS"。以 6.0.0 的措辞为准,使用前应检查你的 Node 版本与所选版本是否匹配。
三、3.1.0:DocumentTransform —— 插件执行前的文档变换管道
3.1.0 是 3.x 中最重要的功能里程碑:引入 DocumentTransform,允许在插件处理 documents 之前对 GraphQL 文档进行修改。
3.1 工作原理
执行时机与调用链可以精确对应到源码:
- 在 packages/graphql-codegen-core/src/codegen.ts,core 读取
options.documentTransforms并调用transformDocuments; - packages/graphql-codegen-core/src/transform-document.ts 按顺序逐个执行 transform,每个 transform 接收
{ documents, schema, config, pluginContext },返回修改后的DocumentFile[]; - 变换后的 documents 才会进入文档校验(validate)与各插件执行阶段。
transform 函数签名定义在 packages/utils/plugins-helpers/src/types.ts:
export type DocumentTransformFunction<Config = object> = (options: { documents: Types.DocumentFile[]; schema: DocumentNode; config: Config; pluginContext?: { [key: string]: any }; }) => Types.Promisable<Types.DocumentFile[]>; export type DocumentTransformObject<T = object> = { transform: DocumentTransformFunction<T>; };3.2 在codegen.ts中使用内联 transform
import type { CodegenConfig } from '@graphql-codegen/cli' const config: CodegenConfig = { schema: 'https://localhost:4000/graphql', documents: ['src/**/*.tsx'], generates: { './src/gql/': { preset: 'client', documentTransforms: [ { transform: ({ documents }) => { // Make some changes to the documents return documents } } ] } } } export default config3.3 实战:用visit删除自定义指令
例如移除@localOnlyDirective(该指令仅存在于本地文档、不应出现在 schema 定义中):
import type { CodegenConfig } from '@graphql-codegen/cli' import { visit } from 'graphql' const config: CodegenConfig = { schema: 'https://localhost:4000/graphql', documents: ['src/**/*.tsx'], generates: { './src/gql/': { preset: 'client', documentTransforms: [ { transform: ({ documents }) => { return documents.map(documentFile => { documentFile.document = visit(documentFile.document, { Directive: { leave(node) { if (node.name.value === 'localOnlyDirective') return null } } }) return documentFile }) } } ] } } } export default config3.4 用文件方式声明 transform
将变换逻辑独立成模块,通过文件名引用:
// my-document-transform.js module.exports = { transform: ({ documents }) => { // Make some changes to the documents return documents } }import type { CodegenConfig } from '@graphql-codegen/cli' const config: CodegenConfig = { schema: 'https://localhost:4000/graphql', documents: ['src/**/*.tsx'], generates: { './src/gql/': { preset: 'client', documentTransforms: ['./my-document-transform.js'] } } } export default configCLI 侧的文件加载逻辑见 packages/graphql-codegen-cli/src/documentTransforms.ts:它会按@graphql-codegen/<name>、@graphql-codegen/<name>-document-transform、<name>、当前工作目录解析路径的顺序尝试加载,并给出清晰的可安装包提示。此外还支持带配置的 transform({ [transformName]: config }形式,见同文件isTransformFileConfig分支),配置会与顶层options.config合并后传给 transform(见 packages/graphql-codegen-core/src/transform-document.ts)。
一个典型用途:把
@client/@rest等客户端专用指令在生成前剥离,或统一注入/改写 fragments。
四、2.x 时代沉淀的关键能力
2.x 的多次 Minor 变更奠定了当前 core 的能力基座,很多能力至今仍在使用。
4.1skipDocumentsValidation(2.2.0)
2.2.0 引入"用skipDocumentsValidation跳过某些指定校验规则"的能力。其语义在 packages/graphql-codegen-core/src/utils.ts 中有完整实现,分为三个维度:
| 取值 | 效果 |
|---|---|
true | 跳过全部文档校验(重复校验 + 对 schema 校验) |
{ skipDuplicateValidation: true } | 仅跳过重复定义校验 |
{ skipValidationAgainstSchema: true } | 仅跳过对 schema 的校验 |
{ ignoreRules: [...] } | 保留校验,但忽略指定的 GraphQL 规则 |
ignoreRules的实际作用见 packages/graphql-codegen-core/src/codegen.ts:默认忽略NoUnusedFragments、NoUnusedVariables、KnownDirectives三条规则,ignoreRules追加进忽略列表后再执行validateGraphQlDocuments。当同时提供 schema hash 与options.cache时,校验结果会按[schemaHash, ...documentHashes, fragments]组成的 key 缓存,避免重复校验(同文件cacheKey逻辑,这也是 2.5.1 "Cache validation of documents" 的延续)。
配置示例:
const config: CodegenConfig = { schema: './schema.graphql', documents: ['./src/**/*.graphql'], skipDocumentsValidation: { ignoreRules: ['NoUnusedFragments'], }, generates: { './src/types.ts': { plugins: ['typescript'] } }, };4.2 重复定义检测(2.6.6 修复)
2.6.6 修复了 fragment/operation 命名冲突的校验问题。检测逻辑在 packages/graphql-codegen-core/src/codegen.ts:core 会遍历所有文档文件,按kind + name建立映射,比对打印后的定义内容;若同名定义内容不同,则抛出异常并列出所有涉及的文件路径,帮助快速定位重复定义来源。
4.3 GraphQL 16 兼容(2.3.0 / 2.4.0)
2.3.0 添加 GraphQL v16 兼容,2.4.0 将其正式纳入 peerDependencies(graphql@16),随后逐步扩展至 17(6.2.0)。
4.4 ESM 支持与 TypeScript 解析修复
- 2.1.0:支持 ESM;
- 2.6.0:支持 TypeScript ESM 模块(
"module": "node16"+"moduleResolution": "node16"); - 2.6.1:修复 CommonJS TypeScript 在
node16/nodenext解析下的类型加载问题。
这些在 package.json 的exports双入口(CJS/ESM 各带独立.d.ts/.d.cts类型)中得到了最终形态。
4.5 性能 Profiler(2.5.0)
2.5.0 引入性能 Profiler(--profile)。在 packages/graphql-codegen-core/src/codegen.ts 中,profiler.run(...)包裹了validateDuplicateDocuments、Create schema instance、Validate documents against schema、每个插件的Plugin <name> execution等关键步骤,可将各阶段耗时输出,用于定位生成瓶颈。
4.6 prepend 排序(1.17.8)
1.17.8 过滤并排序插件返回的prepend/append内容,避免多余空行。排序规则见 packages/graphql-codegen-core/src/codegen.ts:注释(/*、//、*、*/、*/)→package→import→ 其他,保证头部注释与 import 顺序稳定;对应测试见 packages/graphql-codegen-core/tests/prepend.spec.ts。
五、core 的完整执行流水线
综合 6.x 源码,一次codegen()调用的完整顺序为(对应 packages/graphql-codegen-core/src/codegen.ts):
- 重复文档校验:有 documents 且未跳过时执行
validateDuplicateDocuments; - 收集插件附加 schema:调用每个插件的
addToSchema,得到additionalTypeDefs; - Federation 注入:
federation: true且未禁用注入、schema 无 Federation 指令时注入federationSpec(v1 指令/标量); - 合并 schema:无
schemaAst或有附加定义时,用mergeSchemas合并,否则直接使用schemaAst; - 执行 DocumentTransform:按顺序变换 documents;
- 对 schema 校验 documents:按
skipDocumentsValidation控制,支持缓存; - 执行每个插件:依次调用
executePlugin,收集字符串输出或{ prepend, append, content }复合输出; - 拼装最终结果:
prepend(排序后) + 各插件内容 +append,过滤空值后以换行拼接。
这条流水线同时解释了@graphql-codegen/plugin-helpers中Types.GenerateOptions(含documents、schema、schemaAst、config、plugins、pluginMap、documentTransforms、skipDocumentsValidation、cache、profiler等字段)的职责分配。
六、升级与使用建议
- Node 版本:以你选用的 core 版本的
engines与破坏性变更说明为准,升级 major 版本前先核对 Node 版本(当前仓库 packages/graphql-codegen-core/package.json 声明>=16,而 6.0.0 起不再支持 Node 20 之前的旧 LTS,实际请按发行说明判断); - Federation 用户:使用 Federation v2 子图时建议显式设置
disableFederationDirectiveAndScalarInjection: true,避免 v1 指令被自动注入; - 文档校验瓶颈:大批量文档时可用
skipDocumentsValidation: { ignoreRules: [...] }精确豁免规则,而非全量关闭; - 需要预处理文档:优先使用
documentTransforms(内联函数或独立文件均可),它发生在校验与插件执行之前,是"先改写、再生成"的标准入口; - 程序化集成:如需在自有构建脚本中调用,直接使用
codegen(options)与executePlugin这两个公开 API。
参考文件索引
- 变更记录主体:packages/graphql-codegen-core/CHANGELOG.md
- 核心流水线实现:packages/graphql-codegen-core/src/codegen.ts
- DocumentTransform 执行器:packages/graphql-codegen-core/src/transform-document.ts
- 插件执行器:packages/graphql-codegen-core/src/execute-plugin.ts
- 校验/Federation 工具函数:packages/graphql-codegen-core/src/utils.ts
- CLI 侧 transform 加载:packages/graphql-codegen-cli/src/documentTransforms.ts
- 类型定义:packages/utils/plugins-helpers/src/types.ts
- 测试示例:packages/graphql-codegen-core/tests/prepend.spec.ts
- 开发工具
【免费下载链接】graphql-code-generator
A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
相关推荐
MarkText muya 编辑器核心版本演进:从 @muyajs/core 0.0.x 到 0.2.0 的变更全解与源码实证
MarkText muya 编辑器核心版本演进:从 @muyajs/core 0.0.x 到 0.2.0 的变更全解与源码实证 本文以 packages/muy
桌面应用富文本@graphql-codegen/typescript-resolvers 演进全解:从配置项变革到 Federation 与 Scalar 类型系统的实战指南
@graphql codegen/typescript resolvers 演进全解:从配置项变革到 Federation 与 Scalar 类型系统的实战指南
开发工具OpenVINO:开源AI推理优化与部署工具,PyTorch与ONNX模型本地高效运行指南
OpenVINO:开源AI推理优化与部署工具,PyTorch与ONNX模型本地高效运行指南 OpenVINO™ 是一个用于优化和部署AI推理的开源工具包:它把用
人工智能推理引擎深度学习本地部署模型优化模型量化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考