ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

@graphql-codegen/typescript-document-nodes:为 GraphQL 操作生成内嵌文档节点的 TypeScript 模块

@graphql-codegen/typescript-document-nodes:为 GraphQL 操作生成内嵌文档节点的 TypeScript 模块 开发工具【免费下载链接】graphql-code-generatorA tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.项目地址https://gitcode.com/gh_mirrors/gr/graphql-code-generator点击查看免费下载graphql-codegen/typescript-document-nodes是 GraphQL Code Generatorgraphql-code-generator官方插件家族中专门负责文档节点生成的一员它读取你的.graphql文件query / mutation / subscription / fragment为每个命名操作输出一个导出的 TypeScript 常量值是通过gql标签包裹的 GraphQL 文档字符串并可附带DocumentNode类型标注。本文以该插件的 CHANGELOG.md 的版本演进为主线结合 插件源码、Visitor 实现 与 测试用例完整讲解它的工作原理、全部配置项、生成结果形态以及版本兼容边界读完即可在项目中正确接入并定制该插件。一、插件定位把文档变成可导入的模块与typescript-operations生成操作的类型定义不同typescript-document-nodes的目标是让每一个 GraphQL 文档直接成为 TypeScript 模块里的导出常量。官方文档 typescript-document-nodes.mdx 给出了最直观的输入输出对输入viewer.query.graphqlquery Viewer { viewer { login name } }生成在默认配置下import { DocumentNode } from graphql import gql from graphql-tag export const viewerQuery: DocumentNode gql query Viewer { viewer { login name } } 从包描述看它被定义为generating TypeScript modules with embedded GraphQL document nodes见 package.json即文档节点AST以字符串形式内嵌进 TS 源码而不是在运行时把 SDL 解析为 AST。这种产物非常适合配合 Apollo Client、graphql-request 等需要DocumentNode的客户端直接 import 使用。从源码结构看插件入口 src/index.ts 的核心流程是用concatAST把所有DocumentFile的 AST 合并从定义中筛出FRAGMENT_DEFINITION节点连同config.externalFragments组装成LoadedFragment[]实例化TypeScriptDocumentNodesVisitor继承自ClientSideBaseVisitor用oldVisit以leave方式遍历 AST最终返回{ prepend: visitor.getImports(), content: 片段定义 各操作定义 }。也就是说访问者visitor 通用客户端侧基类是它的底层实现骨架visitor-plugin-common是它最重要的运行依赖。二、安装与基础接入插件发布名为graphql-codegen/typescript-document-nodes当前仓库内版本为 6.1.0见 package.json采用 ESM/CJS 双格式产物dist/esm/index.js与dist/cjs/index.js并提供双份类型声明.d.ts/.d.cts因此 CJS 与 ESM 项目均可使用。运行环境要求 Node.js 16。安装方式在你的业务项目中执行pnpm add -D graphql-codegen/cli graphql-codegen/typescript-document-nodes graphql-tag在codegen.ts中注册插件import type { CodegenConfig } from graphql-codegen/cli; const config: CodegenConfig { schema: schema.graphql, documents: [src/**/*.graphql], generates: { src/graphql/documents.ts: { plugins: [typescript-document-nodes], }, }, }; export default config;运行pnpm codegen后src/graphql/documents.ts中即为每个命名操作对应的export const ... gql\... 常量。值得注意的输出约束插件自带的validate校验函数要求输出文件必须以.ts结尾否则直接抛出错误见 src/index.ts因此生成路径不能写成.d.ts、.tsx或其它扩展名。三、生成产物形态三种典型场景仓库中的单元测试 graphql-document-nodes.spec.ts 用可验证的期望输出完整刻画了该插件的生成行为1. 单文件单操作输入一个query MyQuery { field }输出export const MyQuery gql query MyQuery { field } ;2. 多文件 / 单文件多操作无论操作分散在多个.graphql文件还是集中在一个文件里插件都会为每个命名操作分别生成独立常量测试中同时验证了两种输入形态常量名默认取操作名本身export const MyQuery gql query MyQuery { field } ; export const OtherQuery gql query OtherQuery { field } ;3. 匿名操作被忽略测试 Should ignore unnamed documents 证明query { field }这类没有名称的操作不会生成任何内容——这由 visitor 基于操作name的取值逻辑决定未命名操作在leave阶段不会产出常量。四、全部配置项详解插件公开的配置类型为TypeScriptDocumentNodesRawPluginConfig其每个字段都在 src/index.ts 中以 JSDoc exampleMarkdown形式给出了默认值与用法。以下为完整清单配置项默认值作用namingConventionchange-case-all#pascalCase覆盖生成的常量命名约定namePrefix给操作常量名添加前缀nameSuffix给操作常量名添加后缀fragmentPrefix给片段变量名添加前缀fragmentSuffix给片段变量名添加后缀namePrefix/nameSuffix在 visitor.ts 中被映射为ClientSideBaseVisitor的documentVariablePrefix/documentVariableSuffix而fragmentPrefix/fragmentSuffix则映射为fragmentVariablePrefix/fragmentVariableSuffix——这些字段正是visitor-plugin-common中 client-side-base-visitor.ts 的ClientSideBasePluginConfig所定义的核心命名能力。1. namingConvention三种写法全局覆盖所有名称统一用小写const config: CodegenConfig { generates: { src/gql/documents.ts: { plugins: [typescript-document-nodes], config: { namingConvention: change-case-all#lowerCase, }, }, }, };按类型分别指定typeNames作用于操作/片段类型名enumValues作用于枚举值config: { namingConvention: { typeNames: change-case-all#pascalCase, enumValues: change-case-all#upperCase, }, },保持原名不动config: { namingConvention: keep, },change-case-all提供的可用转换函数包括camelCase、capitalCase、constantCase、dotCase、headerCase、noCase、paramCase、pascalCase、pathCase、sentenceCase、snakeCase、lowerCase、upperCase等格式必须是合法的module#method例如change-case-all#pascalCase。下划线处理默认行为是保留下划线。测试用例证实了这一点namingConvention: change-case-all#pascalCasetransformUnderscore: false时query My_Query生成export const My_Query gql\...下划线保留若需去掉下划线则配置为对象形式并开启transformUnderscore: trueconfig: { namingConvention: { typeNames: change-case-all#pascalCase, transformUnderscore: true, }, },此时query My_Query生成export const MyQuery gql\...GraphQL 文档字符串中的名字不受影响仍是My_Query仅 TS 常量名被转换。2. namePrefix / nameSuffix为常量名加前后缀适合避免命名冲突或形成统一命名空间。测试中namePrefix: Graphql产生export const GraphqlMyQuerynameSuffix: Query产生export const MyQueryQuery。官方示例config: { namePrefix: gql, // 生成 gqlMyQuery },config: { nameSuffix: Query, // 生成 MyQueryQuery },五、Fragment 的处理内插而非展开该插件不会把片段内联展开到操作里而是把片段也生成为独立常量并在操作字符串中用${FragmentName}模板插值引用。测试 should contain fragment definitions 给出了完整样例输入同一文件内含片段与两个查询fragment fragment1 on User { id username } query user { user(id: 1) { ...fragment1 } } query user2 { user2: user(id: 1) { ...fragment1 email } }输出export const Fragment1 gql fragment fragment1 on User { id username } ; export const User gql query user { user(id: 1) { ...fragment1 } } ${Fragment1}; export const User2 gql query user2 { user2: user(id: 1) { ...fragment1 email } } ${Fragment1};这意味着生成文件可以直接在支持gql模板插值的运行时如graphql-tag、Apollo 客户端中正确组合片段且多个操作复用同一片段常量避免重复声明。片段常量名同样受namingConvention、fragmentPrefix、fragmentSuffix影响。此外index.ts会合并config.externalFragments中声明的外部片段isExternal: false标记从而支持跨文件引用预先生成的片段。六、版本演进与兼容边界来自 CHANGELOG 的核心信号CHANGELOG.md 记录了该插件从 1.x 到 6.x 的关键演化其中对使用者最有价值的信号集中在最新几个版本6.1.0当前版本依赖更新graphql的 peer 依赖范围扩展为^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在 6.1.0 之前为最高到^16.0.0即新增了对 GraphQL 17 的兼容同步升级graphql-codegen/plugin-helpers7.1.0与graphql-codegen/visitor-plugin-common7.2.0。6.0.0两个破坏性变更Drop Node 20 support最低运行环境提升到 Node 22。变更说明给出的理由值得关注Node 22 原生支持require()加载 ESM 模块使 ESM-only 依赖更容易被集成因此可以放心使用纯 ESM 的包依赖同步升级到graphql-codegen/plugin-helpers7.0.0、graphql-codegen/visitor-plugin-common7.0.0并将auto-bind从~4.0.0升级到^5.0.0auto-bind正是 visitor.ts 中autoBind(this)所依赖的运行时绑定工具。5.0.0破坏性变更Drop Node 18 support同步要求visitor-plugin-common6.0.0、plugin-helpers6.0.0。4.0.0破坏性变更要求 Node.js 16放弃 Node 14。版本演进路线小结版本关键变更兼容性要求2.0.0更新至最新graphql-tools/graphql-configNode 10 不再支持Node 12当时3.0.0Drop Node.js 12 supportNode 144.0.0Drop Node.js 14 supportNode 165.0.0Drop Node 18 supportNode 206.0.0Drop Node 20 support拥抱 ESM-only 生态Node 226.1.0扩展graphqlpeer 依赖至 v17GraphQL 0.8 17此外更早版本还包含几项功能性的里程碑2.1.0 起支持 ESM2.3.0 起支持 TypeScriptmodule: node16与moduleResolution: node16的 ESM 解析2.3.3 修复了moduleResolution: node16/nodenext下 CommonJS 类型解析问题2.2.2 修复了 react-native 项目的 package.json exports1.17.10 起命名约定改用change-case-all。package.json中当前peerDependencies.graphql的完整写法package.json与 CHANGELOG 6.1.0 的记录完全一致可以作为升级时的权威依据。七、质量保障与验证方式该插件在仓库内通过 Vitest 驱动测试其 vitest.config.mts 基于仓库根目录的共享配置../../../../vitest.config.mjs合并出独立项目运行pnpm test对应vitest --no-watch即可执行。测试的实现方式有两点值得关注直接调用plugin函数测试把plugin(null, documents, config, { outputFile: })作为纯函数调用不依赖完整 CLI 链路验证的是 visitor 的生成逻辑本身双重断言每个用例既用toBeSimilarStringTo对比期望输出文本又调用graphql-codegen/testing提供的validateTs(mergeOutputs([result]))对生成结果做 TypeScript 语法/类型校验保证产物可编译。如果你的项目升级了该插件尤其是跨越 5.x → 6.x 这样的破坏性版本可以借助graphql-codegen/cli的 codegen 输出配合tsc --noEmit验证生成文件并确认运行环境满足 Node 版本要求。八、在 Codegen 全家桶中的位置从仓库结构看该插件属于packages/plugins/typescript/下的 TypeScript 插件族运行依赖仅两个graphql-codegen/plugin-helpers提供PluginFunction、PluginValidateFn、Types等插件契约与graphql-codegen/visitor-plugin-common提供ClientSideBaseVisitor基类、NamingConvention、LoadedFragment等通用能力二者都以workspace:^方式引用当前仓库源码见 package.json保证 monorepo 内始终与最新的 visitor 基础设施保持一致。若需要与类型定义配套使用可将typescript-document-nodes与typescript、typescript-operations插件同时配置让文档节点常量与类型定义各自落盘。结语graphql-codegen/typescript-document-nodes是一个小而专的生成插件输入是 GraphQL 操作文档输出是开箱即用、可 import 的gql常量模块。理解它的 visitor 骨架ClientSideBaseVisitoroldVisit、命名约定三件套namingConvention/namePrefix/nameSuffix/fragmentPrefix/fragmentSuffix、片段内插策略以及 CHANGELOG 所揭示的 Node/GraphQL 版本边界就能在升级或定制时有的放矢——尤其注意 6.0.0 起 Node 22 的门槛以及 6.1.0 对 GraphQL 17 的支持这两点直接决定你是否能顺利升级到当前版本。赞分享开发工具【免费下载链接】graphql-code-generatorA tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.项目地址https://gitcode.com/gh_mirrors/gr/graphql-code-generator点击查看免费下载相关推荐Gatsby GraphQL Typegen 实战指南为 GraphQL 查询自动生成 TypeScript 类型Gatsby GraphQL Typegen 实战指南为 GraphQL 查询自动生成 TypeScript 类型 GraphQL Typegen 是 Gat前端静态站点Web框架Apollo Client 4.x 与 GraphQL Codegen为 TypeScript 与 React 应用生成类型安全的查询代码Apollo Client 4.x 与 GraphQL Codegen为 TypeScript 与 React 应用生成类型安全的查询代码 本指南以 Apol前端GraphQLMac Mouse Fix完全指南让普通鼠标在macOS上超越触控板体验Mac Mouse Fix完全指南让普通鼠标在macOS上超越触控板体验 你是不是也觉得在macOS上用第三方鼠标特别憋屈滚动生硬得像在砂纸上摩擦侧键完全开发工具上一篇如何安装vim-javascript-syntax3种主流Vim插件管理器配置指南下一篇PyPOTS核心架构深度解析BaseModel与BaseNNModel设计原理揭秘创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表