ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Gatsby GraphQL Typegen 完整指南:用自动生成类型告别手写查询类型

Gatsby GraphQL Typegen 完整指南:用自动生成类型告别手写查询类型 Gatsby GraphQL Typegen 完整指南用自动生成类型告别手写查询类型【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby导读本指南讲解 Gatsby 的GraphQL Typegen自动类型生成功能只要在gatsby-config中开启graphqlTypegenGatsby 就会在gatsby develop时根据你的 GraphQL 查询与 schema 自动生成 TypeScript 类型默认输出到src/gatsby-types.d.ts并为你提供 IDE 内联提示IntelliSense、GraphQL 查询自动补全与 ESLint 校验。读完本文你将掌握如何开启与配置该功能、使用全局Queries命名空间、配合 GraphQL fragments 复用类型、接入 VSCode GraphQL 插件以及用graphql-eslint强制查询命名规范。适用前提Gatsby 项目使用gatsby4.15.0或更高版本并已按 Gatsby with TypeScript 配置好 TypeScript。该功能默认只在gatsby develop期间生成文件构建阶段不生成。前置条件在开始之前确认你的项目满足以下条件Gatsby 版本gatsby4.15.0或更高版本GraphQL Typegen 在gatsby4.15.0中引入。开启配置项在gatsby-config中将graphqlTypegen设为truemodule.exports { graphqlTypegen: true, }tsconfig.json包含源码目录项目中需要有tsconfig.json且include需覆盖生成文件路径例如{ compilerOptions: { /* ... */ }, include: [./src/**/*] }完整示例可参考仓库中的 examples/using-graphql-typegen/tsconfig.json它额外包含了./gatsby-node.ts、./gatsby-config.ts与./plugins/**/*。可选如果你使用 VSCode可安装 GraphQL 扩展 以获得查询自动补全详见后文配置 VSCode GraphQL 插件一节。使用自动生成的Queries类型为了让示例正常运行请先在gatsby-config的siteMetadata中准备一个title字段module.exports { siteMetadata: { title: My Gatsby Site, }, graphqlTypegen: true, }示例项目的完整配置见 examples/using-graphql-typegen/gatsby-config.ts。第一步启动开发服务器运行gatsby develop。当服务器就绪后你会在终端底部看到一条日志Generating GraphQL and TypeScript types这条日志来自 Gatsby 的 typegen 服务。从源码看该服务依次执行三步写入graphQLTypegen 会调用writeGraphQLSchema写入 schema、writeGraphQLFragments写入 fragments最后调用writeTypeScriptTypes生成 TypeScript 类型整个过程被包裹在 reporter 的活动计时器中。第二步查看生成的类型文件Gatsby 会生成一个类型声明文件默认位于src/gatsby-types.d.ts其中包含你所有查询对应的 TypeScript 类型。你的tsconfig.json需要 include 该文件这样就能在项目任何地方访问Queries命名空间全局declare namespace Queries。第三步创建一个使用类型的页面在src/pages/typegen.tsx创建新页面import * as React from react import { graphql, PageProps } from gatsby const TypegenPage ({ data }: PageProps) { return ( main style{pageStyles} pSite title: TODO/p hr / pQuery Result:/p pre code{JSON.stringify(data, null, 2)}/code /pre /main ) } export default TypegenPage export const query graphql query TypegenPage { site { siteMetadata { title } } } 关键点查询必须有名字如query TypegenPage {}否则自动类型生成无法工作。建议查询名与 React 组件同名并使用 PascalCase 命名。你可以通过graphql-eslint见下文强制执行这一约定。第四步在组件中使用Queries命名空间在 React 组件中访问Queries命名空间并使用TypegenPageQuery类型({ data }: PagePropsQueries.TypegenPageQuery)当你像下面这样写出站点标题时就能获得 TypeScript IntelliSense 提示pSite title: {data.site?.siteMetadata?.title}/p注意这里使用了可选链?.原因见下文Non-Nullable 类型一节。配置gatsby-config中的选项除了布尔值graphqlTypegen还可以设置为一个对象来细化配置module.exports { graphqlTypegen: { typesOutputPath: src/gatsby-types.d.ts, documentSearchPaths: [./gatsby-node.ts, ./plugins/**/gatsby-node.ts], }, }配置项说明typesOutputPath类型文件的输出路径。默认值为src/gatsby-types.d.ts。修改后请同步更新tsconfig.json的include把新路径包含进去。documentSearchPaths覆盖被扫描以提取 GraphQL 查询的文档搜索路径。默认值为./gatsby-node.ts与./plugins/**/gatsby-node.ts见 ts-codegen.ts。从源码看这两个默认值定义在 ts-codegen.tsDEFAULT_TYPES_OUTPUT_PATH src/gatsby-types.d.tsDEFAULT_DOCUMENT_SEARCH_PATHS [./gatsby-node.ts, ./plugins/**/gatsby-node.ts]。同时Joi 校验层joi.ts允许graphqlTypegen为布尔值或对象且两个字段均带默认值说明它们可省略。另外documentSearchPaths的机制值得说明生成gatsby-node.ts中的查询类型时Gatsby 使用loadDocumentsCodeFileLoader扫描这些路径并通过pluckConfig仅提取来自gatsby包的graphql标签模板见 ts-codegen.ts。Non-Nullable 类型由于 Gatsby 推断所有字段除非用户提供了显式 schema字段默认都是可空的。这意味着在 GraphQL Typegen 中字段可能为null——正如上面的示例你必须写成data.site?.siteMetadata?.title因为siteMetadata和title都是可空的。如果你确定siteMetadata.title始终存在可以使用 Gatsby 的 schema 自定义 API 显式声明字段类型import { GatsbyNode } from gatsby export const createSchemaCustomization: GatsbyNode[createSchemaCustomization] ({ actions }) { actions.createTypes( type Site { siteMetadata: SiteMetadata! } type SiteMetadata { title: String! } ) }!表示非空。关于如何显式定义类型可阅读 Customizing the GraphQL schema guide。生成代码的类型选项也印证了可空设计ts-codegen.ts中设置avoidOptionals: true且maybeValue: T | null即字段类型被生成为T | null而非可选属性见 ts-codegen.ts。GraphQL fragmentsFragments 允许你在整个站点中复用 GraphQL 查询的片段并把查询的特定部分与单个文件内聚。可参考 Using GraphQL fragments guide。在 GraphQL Typegen 的语境下fragments 让你能为查询的嵌套部分获得独立的 TypeScript 类型——因为每个 fragment 都会成为自己的 TypeScript 类型。你可以用这些类型来标注消费 GraphQL 数据的组件参数。以下示例同样来自 using-graphql-typegen 示例展示了一个接收buildTime参数的Info组件。该组件和它的SiteInformationfragment 随后被用在src/pages/index.tsx中import * as React from react import { graphql } from gatsby const Info ({ buildTime }: { buildTime?: any }) { return ( p Build time: {buildTime} /p ) } export default Info export const query graphql fragment SiteInformation on Site { buildTime } # Rest of the page above... query IndexPage { site { ...SiteInformation } }这样就会生成一个SiteInformationFragmentTypeScript 类型你可以直接在Info组件中使用const Info ({ buildTime }: { buildTime?: Queries.SiteInformationFragment[buildTime] }) {}仓库示例 examples/using-graphql-typegen/src/components/info.tsx 正是这样实现的对应页面查询见 examples/using-graphql-typegen/src/pages/index.tsx。注意buildTime类型是可空的?这与前面讲的推断字段默认可空一致。此外源码中为 typescript-operations 插件设置了exportFragmentSpreadSubTypes: true见 ts-codegen.ts这保证了 fragment 展开子类型会被导出。Tips保存文件后类型才更新当你给 GraphQL 查询新增字段时需要保存文件自动生成的文件才会更新——生成的文件只在文件保存时刷新。图片类型开箱即用使用gatsby-plugin-image以及 Image CDN时gatsbyImageData与gatsbyImage会自动获得正确的 TypeScript 类型。这是因为生成配置中内置了标量映射GatsbyImageData: import(gatsby-plugin-image).IGatsbyImageData、Date: string、JSON: Recordstring, unknown见 ts-codegen.ts。建议加入.gitignore推荐把src/gatsby-types.d.ts加入.gitignore因为它是机器生成的代码并且信息与页面查询等内容重复。生成文件头部也明确写有/* THIS FILE IS AUTOGENERATED. CHANGES WILL BE LOST ON SUBSEQUENT RUNS. */以及/* eslint-disable */、/* prettier-ignore */标记见 ts-codegen.ts再次印证它不应被手改或提交。配置 VSCode GraphQL 插件在 VSCode 中安装 GraphQL 扩展。在项目根目录创建graphql.config.js内容如下module.exports require(./.cache/typegen/graphql.config.json)VSCode 扩展会读取graphql.config.js并复用 Gatsby.cache目录中的自动生成文件。关于graphql.config.js的更多信息可查看 GraphQL Config 文档。重启 VSCode让 GraphQL 扩展生效。启动开发服务器gatsby develop。打开任意查询例如src/pages下的页面查询使用Ctrl Space也可用Shift Space作为替代快捷键即可获得类似 GraphiQL 的自动补全。该文件从哪来从源码看Gatsby 会生成三份产物到.cache/typegen/目录schema.graphql、fragments.graphql与graphql.config.json见 file-writes.ts。其中graphql.config.json的documents字段被设置为[src/**/**.{ts,js,tsx,jsx}, fragments 文件]即 IDE 会自动扫描src下的源码文件并合并 fragments从而支持跨文件的自动补全。多 GraphQL 项目如果你的仓库包含多个 GraphQL 项目包括 Gatsby可以使用projects键配置module.exports { projects: { site: require(./.cache/typegen/graphql.config.json), other: { // other config } } }子目录场景如果 Gatsby 项目位于子目录例如site配置应改为module.exports require(./site/.cache/typegen/graphql.config.json)graphql-eslint你可以选择使用graphql-eslint来 lint 你的 GraphQL 查询。它能无缝对接上一步创建的graphql.config.js。以下指南假设你还没有任何 ESLint 配置。如果你已经在使用 ESLint需要自行适配你的配置并参考graphql-eslint文档。安装依赖npm install --save-dev eslint graphql-eslint/eslint-plugin typescript-eslint/eslint-plugin typescript-eslint/parser在package.json中添加两个脚本{ scripts: { lint: eslint --ignore-path .gitignore ., lint:fix: npm run lint -- --fix }, }创建.eslintrc.js配置 ESLintmodule.exports { root: true, overrides: [ { files: [*.ts, *.tsx], processor: graphql-eslint/graphql, parser: typescript-eslint/parser, extends: [ eslint:recommended, plugin:typescript-eslint/recommended ], env: { es6: true, }, }, { files: [*.graphql], parser: graphql-eslint/eslint-plugin, plugins: [graphql-eslint], rules: { graphql-eslint/no-anonymous-operations: error, graphql-eslint/naming-convention: [ error, { OperationDefinition: { style: PascalCase, forbiddenPrefixes: [Query, Mutation, Subscription, Get], forbiddenSuffixes: [Query, Mutation, Subscription], }, }, ], }, }, ], }在项目根目录创建graphql.config.jsmodule.exports require(./.cache/typegen/graphql.config.json)启动 Gatsby 开发服务器gatsby develop确认.cache/typegen/graphql.config.json已生成。现在你可以运行npm run lint和npm run lint:fix检查 GraphQL 查询例如它们是否已命名。通过graphql-eslint/no-anonymous-operations规则任何匿名的 GraphQL 操作都会被标记为错误这正好呼应了前文查询必须有名字的硬性要求。额外资源Gatsby with TypeScriptVSCode GraphQL PluginIntelliJ GraphQL Plugingatsby-config Option可运行示例examples/using-graphql-typegen包含gatsby-config.ts、gatsby-node.ts、graphql.config.js、tsconfig.json与完整页面/组件源码【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表