菜单

主题系统

相关源文件

Gatsby 主题系统提供了一个框架,用于将 Gatsby 功能打包成可重用、可组合和可定制的单元。它扩展了标准的 Gatsby 插件系统,允许将完整的站点实现作为 npm 包安装,同时通过一种称为组件遮蔽(component shadowing)的技术实现站点特定的定制。

本文档详细介绍了主题系统在内部如何工作,主题如何与 Gatsby 核心集成,以及开发者如何创建、使用和定制主题。

主题系统架构

Gatsby 主题是专业的插件,它们包含一套完整的 Gatsby 配置文件(gatsby-config.js、gatsby-node.js 等)、组件、模板、样式以及可能的数据。与通常为 Gatsby 构建过程添加特定功能的标准插件不同,主题可以提供完整的站点实现。

主题的配置(插件、数据源等)在构建时会与站点的配置合并。这种合并遵循特定的规则,以确保在使用多个主题时行为可预测。

来源:starters/gatsby-starter-theme-workspace/example/package.json, package.json

组件遮蔽(Component Shadowing)

组件遮蔽是 Gatsby 主题系统的关键创新。它允许站点开发者覆盖主题中的任何组件、模板或资源,而无需完全分叉(fork)或脱离(eject)主题。

遮蔽机制遵循确定性的文件解析模式

例如,要遮蔽来自 gatsby-theme-blog 且位于 src/components/bio.js 的组件,您需要创建

your-site/src/gatsby-theme-blog/components/bio.js

此文件将自动替换主题版本,而无需修改主题本身。遮蔽算法遵循以下查找过程

  1. 在用户站点中主题命名空间下查找组件
  2. 如果未找到,则在主题本身中查找
  3. 对于多主题设置,按声明的反向顺序继续检查每个主题

来源:starters/gatsby-starter-theme-workspace/example/package.json

主题组合

主题可以组合在一起并相互构建,创建可重用的功能层。有两种主要的组合模式

多个独立主题

主题依赖(父/子主题)

组合遵循以下规则

  • 主题可以在其 gatsby-config.js 中包含其他主题
  • Gatsby 以特定顺序加载主题以确保一致的行为
  • 子主题可以遮蔽父主题的组件
  • 配置对象进行深度合并
  • 配置数组(如插件)进行连接

当多个主题一起使用时,必须考虑遮蔽中潜在的命名空间冲突。主题应使用清晰的命名约定以避免冲突。

来源:starters/gatsby-starter-theme-workspace/example/package.json, starters/blog/package.json

主题结构

Gatsby 主题被构建为包含 Gatsby 特定文件的 Node.js 包

gatsby-theme-example/
├── gatsby-config.js    // Theme configuration
├── gatsby-node.js      // Data creation and schema customization
├── gatsby-browser.js   // Browser-specific functionality (optional)
├── gatsby-ssr.js       // Server-side rendering functionality (optional)
├── package.json        // Theme metadata and dependencies
└── src/
    ├── components/     // React components
    ├── templates/      // Page templates
    ├── pages/          // Static pages
    └── hooks/          // React hooks (optional)

要创建可发布的主题

  1. 创建标准 Node.js 包
  2. 将 Gatsby 作为对等依赖项包含
  3. 添加必要的 Gatsby 文件
  4. 导出组件、模板和实用程序
  5. 记录遮蔽和定制选项

来源:starters/gatsby-starter-theme-workspace/example/package.json, package.json

使用主题

要在您的站点中实现 Gatsby 主题

  1. 将主题作为依赖项安装
  1. 将主题添加到您的 gatsby-config.js 中
  1. 直接使用主题的组件,或遮蔽它们以进行定制

使用多个主题时也适用相同的模式。插件数组中主题声明的顺序对于遮蔽优先级很重要。

来源:starters/gatsby-starter-theme-workspace/example/package.json, starters/blog/package.json

主题选项

主题可以接受选项来定制其行为,而无需组件遮蔽。这些选项在站点的 gatsby-config.js 中提供

在主题内部,这些选项可在 gatsby-config.js 和 gatsby-node.js 中访问

主题选项允许主题更灵活,同时保持一致的 API。

来源:starters/gatsby-starter-theme-workspace/example/package.json

主题工作区开发

Gatsby 提供了一个专门用于使用 Yarn 工作区进行主题开发的启动器。这使您能够同时开发主题并使用示例站点进行测试

启动器工作区结构如下

gatsby-starter-theme-workspace/
├── package.json         // Workspace configuration
├── example/             // Example site using the theme
│   ├── gatsby-config.js
│   ├── package.json
│   └── src/
└── gatsby-theme-minimal/ // Theme package
    ├── gatsby-config.js
    ├── package.json
    └── src/

要创建新的主题工作区

此设置通过允许您在示例站点中立即测试更改来简化主题开发。

来源:starters/gatsby-starter-theme-workspace/example/package.json

最佳实践

主题设计

  • 保持主题专注于特定功能
  • 提供合理的默认值和明确的定制选项
  • 为遮蔽机会创建全面的文档
  • 设计具有明确扩展点的组件
  • 建立数据源和处理的约定

主题组合

  • 使用组合创建功能层
  • 考虑创建“核心”主题和扩展主题
  • 记录主题之间的依赖关系
  • 注意多主题设置中的命名冲突

组件遮蔽(Component Shadowing)

  • 组织组件以使遮蔽直观
  • 避免使遮蔽复杂化的深层嵌套
  • 导出更小、更集中的可单独遮蔽的组件
  • 为主题组件使用清晰的命名约定

来源:starters/gatsby-starter-theme-workspace/example/package.json, starters/blog/package.json

实际应用示例

Gatsby 生态系统包含针对常见用例的多个主题

主题目的特性
gatsby-theme-blog博客功能文章、标签、作者
gatsby-theme-notes笔记应用分层笔记、MDX 支持
gatsby-theme-shopify电子商务产品页面、购物车功能
gatsby-theme-documentation文档网站侧边栏导航、搜索

主题可以组合起来创建全面的解决方案。例如,一个带有博客的文档站点可以同时使用 gatsby-theme-documentation 和 gatsby-theme-blog。

来源:starters/blog/package.json, starters/gatsby-starter-wordpress-blog/package.json