05-服务端渲染与元框架——12. Gatsby - 静态站点生成
12. Gatsby - 静态站点生成概述Gatsby 是一个基于 React 的静态站点生成器SSG它从数据源Markdown、CMS、API获取内容在构建时生成静态 HTML 文件提供极快的页面加载速度和优秀的 SEO。维度内容What基于 React 的静态站点生成器Why构建快速、SEO 友好的静态网站When博客、文档、营销网站等静态内容WhereGatsby 项目中使用Who需要静态站点生成的开发者Howexport const query graphql\query { … }1. Gatsby 概述1.1 Gatsby vs Next.js特性GatsbyNext.js主要模式SSG静态生成SSG SSR ISR数据层GraphQL 数据层直接 fetch插件生态丰富的插件较丰富构建时间内容多时较慢较快适用场景博客、文档、营销站各类应用1.2 核心概念// Gatsby 页面组件 import * as React from react; import { graphql } from gatsby; // GraphQL 查询 export const query graphql query HomePageQuery { site { siteMetadata { title } } } ; // 页面组件 export default function HomePage({ data }) { return ( div h1{data.site.siteMetadata.title}/h1 /div ); }2. 页面和路由2.1 文件系统路由# Gatsby 页面结构 src/ ├── pages/ │ ├── index.js → / │ ├── about.js → /about │ ├── contact.js → /contact │ └── blog/ │ ├── index.js → /blog │ └── {mdx.slug}.js → /blog/:slug// src/pages/index.js import * as React from react; import { Link } from gatsby; export default function HomePage() { return ( div h1首页/h1 Link to/about关于我们/Link /div ); } // src/pages/about.js export default function AboutPage() { return ( div h1关于我们/h1 p这是关于页面/p /div ); }2.2 动态路由// src/pages/blog/{mdx.slug}.js import * as React from react; import { graphql } from gatsby; export const query graphql query BlogPostQuery($id: String) { mdx(id: { eq: $id }) { frontmatter { title date } body } } ; export default function BlogPost({ data }) { const post data.mdx; return ( div h1{post.frontmatter.title}/h1 div dangerouslySetInnerHTML{{ __html: post.body }} / /div ); }3. 数据层GraphQL3.1 页面查询// src/pages/blog.js import * as React from react; import { graphql, Link } from gatsby; export const query graphql query BlogPageQuery { allMdx(sort: { frontmatter: { date: DESC } }) { nodes { id frontmatter { title date(formatString: YYYY-MM-DD) } slug } } } ; export default function BlogPage({ data }) { const posts data.allMdx.nodes; return ( div h1博客列表/h1 {posts.map(post ( article key{post.id} h2 Link to{/blog/${post.slug}} {post.frontmatter.title} /Link /h2 p{post.frontmatter.date}/p /article ))} /div ); }3.2 静态查询useStaticQuery// src/components/Header.js import * as React from react; import { useStaticQuery, graphql, Link } from gatsby; export default function Header() { const data useStaticQuery(graphql query HeaderQuery { site { siteMetadata { title } } } ); return ( header h1 Link to/{data.site.siteMetadata.title}/Link /h1 /header ); }4. 完整示例博客站点// gatsby-config.js module.exports { siteMetadata: { title: 我的博客, description: 分享技术和生活, siteUrl: https://example.com, }, plugins: [ gatsby-plugin-image, gatsby-plugin-sharp, gatsby-transformer-sharp, { resolve: gatsby-source-filesystem, options: { name: blog, path: ${__dirname}/content/blog, }, }, { resolve: gatsby-plugin-mdx, options: { extensions: [.mdx, .md], }, }, ], }; // src/pages/index.js import * as React from react; import { graphql, Link } from gatsby; import Layout from ../components/Layout; export const query graphql query HomePageQuery { allMdx(limit: 6, sort: { frontmatter: { date: DESC } }) { nodes { id frontmatter { title date(formatString: YYYY-MM-DD) } excerpt slug } } } ; export default function HomePage({ data }) { const posts data.allMdx.nodes; return ( Layout h1最新文章/h1 {posts.map(post ( article key{post.id} h2 Link to{/blog/${post.slug}} {post.frontmatter.title} /Link /h2 p{post.frontmatter.date}/p p{post.excerpt}/p /article ))} /Layout ); } // src/pages/blog/{mdx.slug}.js import * as React from react; import { graphql } from gatsby; import Layout from ../../components/Layout; export const query graphql query BlogPostQuery($id: String) { mdx(id: { eq: $id }) { frontmatter { title date(formatString: YYYY-MM-DD) } body } } ; export default function BlogPost({ data }) { const post data.mdx; return ( Layout article h1{post.frontmatter.title}/h1 p{post.frontmatter.date}/p div dangerouslySetInnerHTML{{ __html: post.body }} / /article /Layout ); } // src/components/Layout.js import * as React from react; import { useStaticQuery, graphql, Link } from gatsby; export default function Layout({ children }) { const data useStaticQuery(graphql query LayoutQuery { site { siteMetadata { title } } } ); return ( div header h1 Link to/{data.site.siteMetadata.title}/Link /h1 nav Link to/首页/Link Link to/blog博客/Link Link to/about关于/Link /nav /header main{children}/main footer© {new Date().getFullYear()}/footer /div ); }5. 总结核心要点要点说明主要模式静态站点生成SSG数据层GraphQL 统一数据层路由文件系统路由 动态路由适用场景博客、文档、营销网站记忆口诀Gatsby 静态生成快GraphQL 数据统一来博客文档最合适SEO 友好不用猜6. 相关资源Gatsby 官方文档Gatsby 教程Gatsby 插件库