Gatsby 中使用 TypeScript 构建站点的完整实践:基于 using-typescript 示例站点
前端静态站点Web框架【免费下载链接】gatsbyReact-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 APITSX 编写 ├── gatsby-config.ts # 站点配置TS 编写 ├── gatsby-ssr.tsx # SSR APITSX 编写 ├── 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关键点import type只引入类型GatsbyConfig是纯类型导入编译期会被擦除不会产生运行时开销。export default导出配置对象Gatsby 加载配置时通过preferDefault处理默认导出详见下文底层原理。siteMetadata与plugins均有类型约束GatsbyConfig接口定义了siteMetadata、plugins、pathPrefix、trailingSlash、graphqlTypegen、jsxRuntime等字段写错字段名或类型会在编辑器中即时报错。GatsbyConfig接口定义在 packages/gatsby/index.d.ts除示例用到的字段外还包括字段类型说明pathPrefixstring站点部署在子路径如/blog/时使用trailingSlashalways \| never \| ignore控制 URL 尾部斜杠策略assetPrefixstring将静态资源托管到独立域名graphqlTypegenboolean \| GraphQLTypegenOptions自动生成 GraphQL 查询类型见后文扩展方向polyfillboolean是否包含 Promise polyfilljsxRuntimeautomatic \| classic指定 JSX 编译运行时proxyProxy \| Proxy[]开发服务器代理配置headersArrayHeader自定义响应头adapterIAdapter部署平台适配器有了这套类型定义配置文件的字段补全、类型校验都由编辑器与tsc自动完成。tsconfig.jsonTypeScript 编译器配置逐项解读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.tsexport type PageProps DataType object, PageContextType object, LocationState WindowLocation[state], ServerDataType object { path: string uri: string location: WindowLocationLocationState children: undefined params: Recordstring, 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 } }: PagePropsIndexPageProps) { return ( main h1{site.siteMetadata.siteName}/h1 p classNamecustom-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 } } } 这里的核心模式是手动声明查询结果的接口再通过泛型传递给PagePropsinterface IndexPageProps按 GraphQL 查询的返回形状声明类型site → siteMetadata → siteName/sourceUrl组件签名({ data: { site } }: PagePropsIndexPageProps)让data具备完整类型推导site.siteMetadata.siteName的访问不再有any风险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) h1Page 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 classNameglobal-wrapper{children}/div ) export default Layout使用内联对象类型{ children: React.ReactNode }声明 propsReact.ReactNode覆盖元素、字符串、数组、Fragment 等所有合法子节点类型该布局组件通过wrapPageElement包裹每个页面见下节是整个站点类型化组件体系的基础。Browser 与 SSR APIGatsbyBrowser / GatsbySSR 类型Gatsby 的 Browser APIgatsby-browser.tsx与 SSR APIgatsby-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 中实现的两阶段加载策略优先加载编译产物attemptImportCompiled会先尝试从COMPILED_CACHE_DIRGatsby 内部使用 Parcel 编译生成的缓存目录导入已编译的配置模块回退到源码文件若编译产物不存在attemptImportUncompiled再直接导入站点根目录下的原始配置文件并通过resolveJSFilepath同时解析.js/.ts/.tsx/.jsx等扩展名友好的错误诊断当原始文件缺失时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 化的最小改造清单如下安装类型依赖typescript、types/react、types/react-dom、types/node添加tsconfig.json可直接复用示例中的严格模式配置重命名配置文件将gatsby-config.js改为gatsby-config.ts并加上: GatsbyConfig标注gatsby-node.ts、gatsby-browser.tsx、gatsby-ssr.tsx同理分别使用GatsbyNode、GatsbyBrowser、GatsbySSR类型页面组件统一PageProps泛型为每个 GraphQL 查询声明结果接口或开启graphqlTypegen: true让 Gatsby 自动生成查询类型加入 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框架【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址https://gitcode.com/gh_mirrors/ga/gatsby点击查看免费下载相关推荐使用 gatsby-source-faker 为 Gatsby 站点生成模拟数据基于 using-faker 示例的完整实践使用 gatsby source faker 为 Gatsby 站点生成模拟数据基于 using faker 示例的完整实践 本文以仓库 examples/u前端静态站点Web框架Gatsby Minimal TypeScript Starter 上手指南用 TypeScript 从零搭建 Gatsby 站点Gatsby Minimal TypeScript Starter 上手指南用 TypeScript 从零搭建 Gatsby 站点 本篇技术指南围绕 Gats前端静态站点Web框架基于 Gatsby 构建多语言站点的零依赖 i18n 方案using-i18n 示例深度解析基于 Gatsby 构建多语言站点的零依赖 i18n 方案using i18n 示例深度解析 导读 本文围绕 Gatsby 官方仓库中的 using i18n前端静态站点Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考