news 2026/10/11 11:54:11

Gatsby 中使用 TypeScript 构建站点的完整实践:基于 using-typescript 示例站点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gatsby 中使用 TypeScript 构建站点的完整实践:基于 using-typescript 示例站点
  • 前端
  • 静态站点
  • Web框架

【免费下载链接】gatsby

React-based framework with performance, scalability, and security built in.

项目地址:https://gitcode.com/gh_mirrors/ga/gatsby
点击查看免费下载

本篇指南以 Gatsby 官方仓库中的 using-typescript 示例站点 为主体,讲解如何在 Gatsby 项目中全面落地 TypeScript:从tsconfig.json与gatsby-config.ts的编写,到页面组件的PageProps类型安全、GraphQL 查询类型化,再到gatsby-browser.tsx与gatsby-ssr.tsx中使用GatsbyBrowser/GatsbySSR类型编写 Browser 与 SSR API。读完本文,你将掌握一套可直接复制到自有站点的 TypeScript 化改造方案,并理解 Gatsby 底层如何加载和执行.ts格式的配置文件。

示例站点概览:一套完整的 TypeScript Gatsby 应用

examples/using-typescript是一个最小但结构完整的 TypeScript Gatsby 示例站点,其目录结构如下:

examples/using-typescript/ ├── gatsby-browser.tsx # Browser API(TSX 编写) ├── gatsby-config.ts # 站点配置(TS 编写) ├── gatsby-ssr.tsx # SSR API(TSX 编写) ├── package.json ├── styles.css ├── tsconfig.json └── src/ ├── components/ │ └── layout.tsx # 全局布局组件 └── pages/ ├── 404.tsx # 404 页面 └── index.tsx # 首页(含 GraphQL 查询)

这个示例覆盖了 TypeScript 化改造的全部关键位置:

文件说明
gatsby-config.ts使用GatsbyConfig类型标注的站点配置文件
tsconfig.jsonTypeScript 编译配置
src/pages/index.tsx使用PageProps泛型 + GraphQL 查询的页面
src/pages/404.tsx使用PageProps的 404 页面
src/components/layout.tsx带类型标注的布局组件
gatsby-browser.tsx使用GatsbyBrowser类型
gatsby-ssr.tsx使用GatsbySSR类型

依赖与脚本:搭好 TypeScript 开发环境

先看 package.json,它定义了运行与类型检查所需的全部依赖:

{ "scripts": { "start": "gatsby develop", "develop": "gatsby develop", "build": "gatsby build", "type-check": "tsc --noEmit" }, "dependencies": { "gatsby": "next", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@types/node": "^17.0.21", "@types/react": "^17.0.39", "@types/react-dom": "^17.0.11", "typescript": "^4.5.5" } }

值得注意的几点:

  • gatsby以next版本安装:说明该示例跟随 Gatsby 的预发布版本进行验证,实际项目中建议按官方发布线固定版本。
  • 三个@types/*包:@types/react与@types/react-dom为 React 提供类型定义,@types/node为 Node.js 全局 API(如process、path)提供类型,三者是 TSX 组件与 Gatsby Node API 正常编译的前提。
  • type-check脚本:tsc --noEmit只做类型检查、不产出编译产物,可在 CI 或 pre-commit 阶段快速验证全站类型正确性,这也是 TypeScript 化项目建议保留的检查手段。

安装依赖后,使用npm run develop启动开发服务器,或npm run build执行生产构建。

配置类型安全:从 gatsby-config.ts 开始

Gatsby 从 2.x 起即可直接使用.ts作为配置文件。示例中的 gatsby-config.ts 演示了标准写法:

import type { GatsbyConfig } from "gatsby" const config: GatsbyConfig = { siteMetadata: { siteName: `Using TypeScript`, sourceUrl: `https://github.com/gatsbyjs/gatsby/tree/master/examples/using-typescript`, }, plugins: [], } export default config

关键点:

  1. import type只引入类型:GatsbyConfig是纯类型导入,编译期会被擦除,不会产生运行时开销。
  2. export default导出配置对象:Gatsby 加载配置时通过preferDefault处理默认导出(详见下文底层原理)。
  3. siteMetadata与plugins均有类型约束:GatsbyConfig接口定义了siteMetadata、plugins、pathPrefix、trailingSlash、graphqlTypegen、jsxRuntime等字段,写错字段名或类型会在编辑器中即时报错。

GatsbyConfig接口定义在 packages/gatsby/index.d.ts,除示例用到的字段外,还包括:

字段类型说明
pathPrefixstring站点部署在子路径(如/blog/)时使用
trailingSlash"always" \| "never" \| "ignore"控制 URL 尾部斜杠策略
assetPrefixstring将静态资源托管到独立域名
graphqlTypegenboolean \| GraphQLTypegenOptions自动生成 GraphQL 查询类型(见后文扩展方向)
polyfillboolean是否包含 Promise polyfill
jsxRuntime"automatic" \| "classic"指定 JSX 编译运行时
proxyProxy \| Proxy[]开发服务器代理配置
headersArray<Header>自定义响应头
adapterIAdapter部署平台适配器

有了这套类型定义,配置文件的字段补全、类型校验都由编辑器与tsc自动完成。

tsconfig.json:TypeScript 编译器配置逐项解读

tsconfig.json 是示例站点的编译器配置,各选项含义如下:

{ "compilerOptions": { "target": "esnext", "lib": ["dom", "esnext"], "jsx": "react", "module": "esnext", "moduleResolution": "node", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true }, "include": ["./src/**/*"] }

逐项说明:

  • target: "esnext":编译目标为最新 ECMAScript 特性,交由下游打包工具(Gatsby 内部的 webpack/Parcel)进一步转译,避免 TypeScript 层过早降级。
  • lib: ["dom", "esnext"]:启用 DOM 与 ESNext 标准库类型,覆盖浏览器 API 与最新语言特性。
  • jsx: "react":使用经典的 React JSX 运行时。若gatsby-config.ts中设置了jsxRuntime: "automatic",此处可对应改为"react-jsx"。
  • module: "esnext"、moduleResolution: "node":保留 ESM 模块语义,并按 Node 方式解析模块路径。
  • esModuleInterop: true:允许import React from "react"这类默认导入与 CommonJS 模块互操作,示例代码中import * as React from "react"亦依赖该设置。
  • strict: true:开启全部严格模式检查(strictNullChecks、noImplicitAny等),这是类型安全的核心开关。
  • skipLibCheck: true:跳过.d.ts声明文件内部的类型检查,加快编译速度并规避第三方声明文件的兼容问题。
  • include: ["./src/**/*"]:仅将src目录纳入类型检查范围。配置文件(如gatsby-config.ts)由 Gatsby 独立编译,不依赖此include。

页面组件类型安全:PageProps 与 GraphQL 查询

TypeScript 化改造的重头戏是页面组件。Gatsby 为页面组件提供了PageProps泛型类型,定义在 packages/gatsby/index.d.ts:

export type PageProps< DataType = object, PageContextType = object, LocationState = WindowLocation["state"], ServerDataType = object > = { path: string uri: string location: WindowLocation<LocationState> children: undefined params: Record<string, string> pageResources: { ... } data: DataType pageContext: PageContextType }

示例首页 src/pages/index.tsx 完整演示了PageProps与 GraphQL 查询的组合:

import * as React from "react" import { graphql, PageProps } from "gatsby" // 你也可以使用 https://github.com/dotansimha/graphql-code-generator // 从 GraphQL schema 生成类型 interface IndexPageProps { site: { siteMetadata: { siteName: string sourceUrl: string } } } const Index = ({ data: { site } }: PageProps<IndexPageProps>) => { return ( <main> <h1>{site.siteMetadata.siteName}</h1> <p className="custom-text"> This example is hosted on <a href={site.siteMetadata.sourceUrl}>GitHub</a>. </p> </main> ) } export default Index export const pageQuery = graphql` query IndexQuery { site { siteMetadata { siteName sourceUrl } } } `

这里的核心模式是手动声明查询结果的接口,再通过泛型传递给PageProps:

  1. interface IndexPageProps按 GraphQL 查询的返回形状声明类型(site → siteMetadata → siteName/sourceUrl);
  2. 组件签名({ data: { site } }: PageProps<IndexPageProps>)让data具备完整类型推导,site.siteMetadata.siteName的访问不再有any风险;
  3. pageQuery使用graphql模板标签定义查询,Gatsby 构建时会提取该查询执行。

示例注释还提示了一个更自动化的方向:使用graphql-code-generator从 GraphQL schema 直接生成类型,从而避免手工维护接口与查询形状的一致性。此外,当前版本 Gatsby 还内置了graphqlTypegen配置项(GatsbyConfig中的boolean | GraphQLTypegenOptions,见 index.d.ts),开启后可自动生成查询类型,进一步简化类型维护。

404 页面:零数据页面的类型写法

src/pages/404.tsx 演示了不含 GraphQL 查询的页面如何写类型:

import * as React from "react" import { PageProps } from "gatsby" const NotFound = ({}: PageProps) => <h1>Page Not Found!</h1> export default NotFound

未传入泛型参数时,PageProps使用默认的object类型。此写法表明:页面组件的 props 类型应统一使用PageProps,即使该页面没有数据查询,也保持相同的类型约定,便于后续为 404 页添加数据时不改组件签名。

布局组件:children 的类型标注

src/components/layout.tsx 展示了普通组件的类型写法:

import * as React from "react" const Layout = ({ children }: { children: React.ReactNode }) => ( <div className="global-wrapper">{children}</div> ) export default Layout
  • 使用内联对象类型{ children: React.ReactNode }声明 props,React.ReactNode覆盖元素、字符串、数组、Fragment 等所有合法子节点类型;
  • 该布局组件通过wrapPageElement包裹每个页面(见下节),是整个站点类型化组件体系的基础。

Browser 与 SSR API:GatsbyBrowser / GatsbySSR 类型

Gatsby 的 Browser API(gatsby-browser.tsx)与 SSR API(gatsby-ssr.tsx)同样支持 TypeScript 写法,示例中两者共同使用wrapPageElement包裹页面:

// gatsby-browser.tsx import * as React from "react" import type { GatsbyBrowser } from "gatsby" import Layout from "./src/components/layout" import "./styles.css" export const wrapPageElement: GatsbyBrowser["wrapPageElement"] = ({ element }) => { return <Layout>{element}</Layout> }
// gatsby-ssr.tsx import * as React from "react" import type { GatsbySSR } from "gatsby" import Layout from "./src/components/layout" export const wrapPageElement: GatsbySSR["wrapPageElement"] = ({ element }) => { return <Layout>{element}</Layout> }

这种写法的精妙之处:

  • 通过索引访问类型:GatsbyBrowser["wrapPageElement"]直接取出接口中对应 API 的类型签名,Gatsby 会自动推导出wrapPageElement回调的参数({ element, props, ... })与返回值类型,无需手写签名;
  • 一份实现两处复用:浏览器端与 SSR 端使用相同的布局包裹逻辑,保证客户端水合与服务端渲染输出一致;
  • 类型定义来源:GatsbyBrowser与GatsbySSR接口均定义在 packages/gatsby/index.d.ts 与 同文件 SSR 段,其中列出了onClientEntry、onRouteUpdate、wrapRootElement、onPreRenderHTML、replaceHeadComponents等完整 API 及各自的参数结构,可作为编写其他 API 时的类型参考。

同时,styles.css 在gatsby-browser.tsx中被导入,演示了 TypeScript 项目中同样可以引入全局样式资源。

底层原理:Gatsby 如何加载 .ts 配置文件

Gatsby 之所以能直接使用gatsby-config.ts、gatsby-node.ts等 TS 配置文件,得益于 packages/gatsby/src/bootstrap/get-config-file.ts 中实现的两阶段加载策略:

  1. 优先加载编译产物:attemptImportCompiled会先尝试从COMPILED_CACHE_DIR(Gatsby 内部使用 Parcel 编译生成的缓存目录)导入已编译的配置模块;
  2. 回退到源码文件:若编译产物不存在,attemptImportUncompiled再直接导入站点根目录下的原始配置文件,并通过resolveJSFilepath同时解析.js/.ts/.tsx/.jsx等扩展名;
  3. 友好的错误诊断:当原始文件缺失时,checkTsAndNearMatch会检测是否存在同名.ts文件(用于提示"存在 gatsby-config.ts 但缺少编译产物")、是否存在命名近似的文件、以及配置是否被错误放进了src/目录,并分别抛出带有专属错误码(如10123、10124、10125、10127)的提示信息。

这套流程保证了:开发者写的gatsby-config.ts既能在开发时被直接识别,也能在生产构建中复用编译缓存,而无需手工将配置转成 JS。

运行验证与类型检查

在examples/using-typescript目录下依次执行:

npm install # 安装依赖 npm run type-check # 仅类型检查(tsc --noEmit) npm run develop # 启动开发服务器,访问 http://localhost:8000 npm run build # 生产构建

npm run type-check会在不产出任何文件的前提下校验全站类型;develop与build则由 Gatsby 完成 GraphQL 查询提取、页面生成与静态输出。首页渲染的内容(站点名称与示例说明)来自siteMetadata的 GraphQL 查询结果,可直接验证从配置到页面渲染的完整数据链路。

扩展方向:把示例迁移到你的项目

基于该示例,将自有站点 TypeScript 化的最小改造清单如下:

  1. 安装类型依赖:typescript、@types/react、@types/react-dom、@types/node;
  2. 添加tsconfig.json:可直接复用示例中的严格模式配置;
  3. 重命名配置文件:将gatsby-config.js改为gatsby-config.ts并加上: GatsbyConfig标注;gatsby-node.ts、gatsby-browser.tsx、gatsby-ssr.tsx同理分别使用GatsbyNode、GatsbyBrowser、GatsbySSR类型;
  4. 页面组件统一PageProps泛型:为每个 GraphQL 查询声明结果接口,或开启graphqlTypegen: true让 Gatsby 自动生成查询类型;
  5. 加入 CI 检查:在 CI 中运行npm run type-check,把类型错误拦截在合并之前。

需要注意的前提是:示例基于gatsby: next预发布版本与 TypeScript 4.5、React 18.2 验证,迁移到自己的项目时应以实际安装的 Gatsby 版本对应的类型声明(packages/gatsby/index.d.ts)为准。

总结

using-typescript示例虽然体量小,却完整覆盖了 TypeScript 化 Gatsby 站点的所有关键面:类型化的配置文件、严格模式的tsconfig.json、PageProps泛型驱动的页面数据、GatsbyBrowser/GatsbySSR索引类型标注的 API 实现,以及底层对.ts配置文件的编译加载机制。以此为模板,你可以快速为自己的 Gatsby 项目建立完整的类型安全保障。

  • 前端
  • 静态站点
  • Web框架

【免费下载链接】gatsby

React-based framework with performance, scalability, and security built in.

项目地址:https://gitcode.com/gh_mirrors/ga/gatsby
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 11:54:04

无穹玩法 | 用MCP把产品文档自动生成官网工作流改到TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/11 11:53:44

AI Coding实践:从需求拆解到生产级代码的工程化落地

先说个现象&#xff1a;现在很多人用AI写代码&#xff0c;确实能跑通Demo&#xff0c;但一提到“生产级”三个字&#xff0c;就露馅了。尤其是效果广告引擎这种对延迟、并发、稳定性极度敏感的系统&#xff0c;AI生成的结构性代码往往只是“看起来像那么回事”&#xff0c;真要…

作者头像 李华
网站建设 2026/10/11 11:53:06

阿里Java并发编程全优笔记:程序员突击必备!

现在Java面试&#xff0c;问的是越来越底层。基本上规模大点的互联网公司都会对JVM&#xff0c;OS&#xff0c;算法&#xff0c;线程&#xff0c;IO等底层知识进行深入考察&#xff1b;其中粉丝反馈近期出去面试被问的最多&#xff0c;频次最高的技术栈当属多线程并发编程了。说…

作者头像 李华
网站建设 2026/10/11 11:53:05

CNN+LSTM在线流量分类:从PCAP预处理到实时预测完整指南

简介&#xff1a;这是一份面向高校课程设计或期末大作业场景的在线流量分类项目&#xff0c;整体采用CNN与LSTM相结合的时空神经网络&#xff0c;可对正常业务流量、恶意软件流量及网络攻击流量进行实时识别与可视化展示。项目已完成全部代码调试&#xff0c;在导师指导下获评9…

作者头像 李华