Gatsby 中文教程
1. 什么是 Gatsby?
Gatsby 是一个基于 React 的开源静态站点生成器 (SSG),专注于构建高性能、SEO 友好的网站。它由 Kyle Mathews 创建,通过 GraphQL 层连接数据源和 React 组件,生成完全静态的 HTML、CSS 和 JavaScript 文件。
1.1 Gatsby 的核心优势
- 极致性能:预加载资源、代码拆分、图像优化等技术,提供接近瞬时的页面加载体验。
- SEO 友好:静态生成的 HTML 对搜索引擎非常友好,提高网站排名。
- 丰富的插件生态:通过插件系统集成各种数据源和功能。
- GraphQL 数据层:统一的数据查询接口,简化数据获取和管理。
- 开发体验:热模块替换、快速刷新等功能,提高开发效率。
- 部署便捷:生成的静态文件可以部署到任何静态托管服务。
- 现代化技术栈:基于 React、GraphQL 和 Webpack,使用最新的前端技术。
2. 安装和初始化
2.1 使用 gatsby-cli 初始化项目
# 安装 gatsby-cli
npm install -g gatsby-cli
# 初始化项目
gatsby new my-gatsby-site
# 进入项目目录
cd my-gatsby-site
# 启动开发服务器
gatsby develop2.2 选择模板
Gatsby 提供了多种官方模板,可以根据需要选择:
# 使用默认模板
gatsby new my-gatsby-site
# 使用博客模板
gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog
# 使用电商模板
gatsby new my-ecommerce https://github.com/gatsbyjs/gatsby-starter-ecommerce
# 使用文档模板
gatsby new my-docs https://github.com/gatsbyjs/gatsby-starter-docs2.3 手动安装
如果你想手动安装 Gatsby,可以按照以下步骤:
# 创建项目目录
mkdir my-gatsby-site
cd my-gatsby-site
# 初始化 package.json
npm init -y
# 安装依赖
npm install gatsby react react-dom
# 添加脚本
# 在 package.json 中添加:
# "scripts": {
# "develop": "gatsby develop",
# "build": "gatsby build",
# "serve": "gatsby serve",
# "clean": "gatsby clean"
# }
# 创建 gatsby-config.js 配置文件
# echo "module.exports = { plugins: [] }" > gatsby-config.js2.4 验证安装
# 启动开发服务器
gatsby develop
# 访问 http://localhost:8000
# 访问 GraphQL playground
# http://localhost:8000/___graphql3. 基本目录结构
Gatsby 项目的默认目录结构如下:
my-gatsby-site/
├── src/ # 源代码目录
│ ├── components/ # React 组件
│ ├── pages/ # 页面组件(自动生成路由)
│ ├── templates/ # 模板组件(用于动态生成页面)
│ ├── images/ # 图像资源
│ ├── styles/ # 样式文件
│ └── utils/ # 工具函数
├── public/ # 构建输出目录
├── static/ # 静态资源(直接复制到输出目录)
├── gatsby-config.js # Gatsby 配置文件
├── gatsby-node.js # Node.js API 配置
├── gatsby-browser.js # 浏览器 API 配置
├── gatsby-ssr.js # SSR API 配置
├── package.json # 项目配置文件
└── README.md # 项目说明文件4. 核心功能
4.1 页面创建
Gatsby 支持两种创建页面的方式:
4.1.1 文件系统路由
在 src/pages 目录中创建 React 组件,Gatsby 会自动为其生成路由:
// src/pages/index.js
import React from 'react';
export default function Home() {
return (
<div>
<h1>Hello Gatsby!</h1>
<p>Welcome to your new Gatsby site.</p>
</div>
);
}
// src/pages/about.js
import React from 'react';
export default function About() {
return (
<div>
<h1>About Us</h1>
<p>This is the about page.</p>
</div>
);
}4.1.2 编程式创建页面
在 gatsby-node.js 中使用 API 编程式创建页面:
// gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions;
// 查询数据
const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
frontmatter {
path
}
}
}
}
}
`);
// 创建页面
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: require.resolve('./src/templates/blog-post.js'),
context: {
// 传递给模板的数据
slug: node.frontmatter.path,
},
});
});
};4.2 数据获取
Gatsby 使用 GraphQL 来获取和管理数据:
4.2.1 页面数据查询
在页面组件中使用 pageQuery 静态属性定义 GraphQL 查询:
// src/pages/blog.js
import React from 'react';
import { graphql } from 'gatsby';
export default function Blog({ data }) {
const posts = data.allMarkdownRemark.edges;
return (
<div>
<h1>Blog</h1>
<ul>
{posts.map(({ node }) => (
<li key={node.id}>
<h2>{node.frontmatter.title}</h2>
<p>{node.excerpt}</p>
</li>
))}
</ul>
</div>
);
}
export const pageQuery = graphql`
query BlogQuery {
allMarkdownRemark {
edges {
node {
id
frontmatter {
title
date
}
excerpt
}
}
}
}
`;4.2.2 组件数据查询
在非页面组件中使用 useStaticQuery 钩子获取数据:
// src/components/Header.js
import React from 'react';
import { useStaticQuery, graphql } from 'gatsby';
export default function Header() {
const data = useStaticQuery(graphql`
query HeaderQuery {
site {
siteMetadata {
title
}
}
}
`);
return (
<header>
<h1>{data.site.siteMetadata.title}</h1>
</header>
);
}4.3 插件系统
Gatsby 的插件系统允许你扩展核心功能,以下是一些常用的插件:
4.3.1 数据源插件
- gatsby-source-filesystem:从文件系统读取数据
- gatsby-source-wordpress:从 WordPress 获取数据
- gatsby-source-contentful:从 Contentful CMS 获取数据
- gatsby-source-strapi:从 Strapi CMS 获取数据
4.3.2 转换插件
- gatsby-transformer-remark:处理 Markdown 文件
- gatsby-transformer-json:处理 JSON 文件
- gatsby-transformer-yaml:处理 YAML 文件
- gatsby-transformer-sharp:处理图像
4.3.3 功能插件
- gatsby-plugin-image:图像优化
- gatsby-plugin-sharp:图像处理
- gatsby-plugin-react-helmet:管理文档头部
- gatsby-plugin-sitemap:生成站点地图
- gatsby-plugin-robots-txt:生成 robots.txt
- gatsby-plugin-manifest:生成 PWA 清单
- gatsby-plugin-offline:启用离线功能
4.4 图像优化
Gatsby 提供了强大的图像优化功能,通过 gatsby-plugin-image 和 gatsby-plugin-sharp 插件实现:
// src/components/OptimizedImage.js
import React from 'react';
import { StaticImage } from 'gatsby-plugin-image';
export default function OptimizedImage() {
return (
<div>
<h2>优化后的图像</h2>
<StaticImage
src="../images/example.jpg"
alt="Example image"
width={800}
height={600}
placeholder="blurred"
quality={90}
/>
</div>
);
}对于动态图像,可以使用 gatsbyImageData:
// src/components/DynamicImage.js
import React from 'react';
import { GatsbyImage, getImage } from 'gatsby-plugin-image';
export default function DynamicImage({ imageData }) {
const image = getImage(imageData);
return (
<GatsbyImage
image={image}
alt="Dynamic image"
/>
);
}4.5 路由和链接
Gatsby 使用 gatsby-link 组件实现客户端路由:
// src/components/Nav.js
import React from 'react';
import { Link } from 'gatsby';
export default function Nav() {
return (
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/blog">Blog</Link></li>
</ul>
</nav>
);
}5. 高级特性
5.1 页面预加载
Gatsby 会自动预加载视口中的链接,提高导航速度:
// src/components/BlogPost.js
import React from 'react';
import { Link } from 'gatsby';
export default function BlogPost({ post }) {
return (
<div>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
{/* 此链接会被自动预加载 */}
<Link to={`/blog/${post.slug}`}>Read more</Link>
</div>
);
}5.2 代码拆分
Gatsby 自动进行代码拆分,减少初始加载体积:
// src/components/LazyComponent.js
import React, { lazy, Suspense } from 'react';
// 动态导入组件
const HeavyComponent = lazy(() => import('./HeavyComponent'));
export default function LazyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
}5.3 PWA 支持
通过插件启用 PWA 功能:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `My Gatsby Site`,
short_name: `Gatsby Site`,
description: `A Gatsby site`,
start_url: `/`,
background_color: `#ffffff`,
theme_color: `#0070f3`,
display: `standalone`,
icon: `src/images/icon.png`,
},
},
`gatsby-plugin-offline`,
],
};5.4 国际化
使用插件实现国际化支持:
# 安装插件
npm install gatsby-plugin-intl// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-intl`,
options: {
path: `${__dirname}/src/intl`,
languages: [`en`, `zh`],
defaultLanguage: `en`,
redirect: true,
},
},
],
};// src/intl/en.json
{
"title": "Hello",
"description": "Welcome to my site"
}
// src/intl/zh.json
{
"title": "你好",
"description": "欢迎访问我的网站"
}
// src/components/TranslatedComponent.js
import React from 'react';
import { useIntl } from 'gatsby-plugin-intl';
export default function TranslatedComponent() {
const intl = useIntl();
return (
<div>
<h1>{intl.formatMessage({ id: 'title' })}</h1>
<p>{intl.formatMessage({ id: 'description' })}</p>
</div>
);
}6. 最佳实践
6.1 性能优化
- 使用静态图像:对于固定图像,使用
StaticImage组件。 - 优化动态图像:对于动态图像,使用
gatsbyImageData并设置适当的参数。 - 代码拆分:使用动态导入减少初始加载体积。
- 缓存策略:合理设置缓存头,减少重复请求。
- 减少第三方脚本:只加载必要的第三方脚本,避免阻塞页面加载。
- 使用字体子集:只包含使用的字符,减少字体文件大小。
6.2 目录结构
my-gatsby-site/
├── src/ # 源代码目录
│ ├── components/ # 可复用组件
│ │ ├── ui/ # UI 组件
│ │ └── layout/ # 布局组件
│ ├── pages/ # 页面组件
│ ├── templates/ # 模板组件
│ ├── images/ # 图像资源
│ ├── styles/ # 样式文件
│ ├── utils/ # 工具函数
│ └── intl/ # 国际化文件
├── static/ # 静态资源
├── gatsby-config.js # Gatsby 配置
├── gatsby-node.js # Node.js API 配置
├── gatsby-browser.js # 浏览器 API 配置
├── gatsby-ssr.js # SSR API 配置
└── package.json # 项目配置6.3 部署策略
Gatsby 生成的静态文件可以部署到任何静态托管服务:
6.3.1 Netlify
- 将代码推送到 GitHub、GitLab 或 Bitbucket
- 在 Netlify 上导入项目
- 配置构建命令:
gatsby build - 配置发布目录:
public - 部署完成后获得一个 URL
6.3.2 Vercel
- 将代码推送到 GitHub、GitLab 或 Bitbucket
- 在 Vercel 上导入项目
- 配置构建命令:
gatsby build - 配置发布目录:
public - 部署完成后获得一个 URL
6.3.3 GitHub Pages
- 安装
gh-pages插件:npm install gh-pages - 在
package.json中添加脚本:"deploy": "gatsby build && gh-pages -d public" - 运行部署命令:
npm run deploy - 部署到
https://<username>.github.io/<repository-name>
6.4 安全最佳实践
- 环境变量:使用
.env文件存储敏感信息 - 输入验证:验证用户输入,防止 XSS 和注入攻击
- 依赖管理:定期更新依赖,修复安全漏洞
- HTTPS:确保网站使用 HTTPS 协议
- 内容安全策略:配置适当的 CSP 头,防止恶意脚本执行
7. 常见问题与解决方案
7.1 数据查询问题
问题:GraphQL 查询返回空数据
解决方案:
- 检查数据源插件是否正确配置
- 确保数据文件存在且格式正确
- 在 GraphiQL 中测试查询,确认语法正确
- 检查
gatsby-node.js中的数据处理逻辑
7.2 图像优化问题
问题:图像不显示或优化失败
解决方案:
- 确保安装了
gatsby-plugin-image和gatsby-plugin-sharp - 检查图像路径是否正确
- 确保图像文件存在
- 检查插件配置是否正确
7.3 构建问题
问题:gatsby build 失败
解决方案:
- 检查控制台错误信息,定位具体问题
- 确保所有依赖都已正确安装
- 检查
gatsby-config.js和gatsby-node.js中的配置 - 清除缓存后重试:
gatsby clean && gatsby build
7.4 部署问题
问题:部署后页面空白
解决方案:
- 检查浏览器控制台错误信息
- 确保所有资源路径正确(特别是静态资源)
- 检查路由配置是否正确
- 确保使用了相对路径或正确的绝对路径
7.5 性能问题
问题:页面加载缓慢
解决方案:
- 使用 Gatsby 分析工具:
gatsby build --analyze - 优化图像:使用
StaticImage或gatsbyImageData - 减少初始加载体积:使用代码拆分和动态导入
- 优化第三方脚本:延迟加载非关键脚本
- 启用浏览器缓存:配置适当的缓存头
8. 总结
Gatsby 是一个功能强大的静态站点生成器,它通过预加载、代码拆分、图像优化等技术,提供了极致的性能体验。同时,它的插件生态系统和 GraphQL 数据层,使得开发和数据管理变得更加简单和高效。
通过本教程,你应该已经了解了 Gatsby 的基本概念、核心功能和最佳实践。Gatsby 非常适合构建博客、企业网站、电商网站等各种类型的静态网站,它的现代化技术栈和优秀的开发体验,使得前端开发变得更加愉悦和高效。
随着 Gatsby 的不断发展,新的特性和改进不断推出,建议你关注官方文档和更新日志,保持对最新功能的了解。无论你是构建个人网站还是企业应用,Gatsby 都能为你提供出色的解决方案。