Gatsby Hello World — 静态博客站点
目标
创建一个 Gatsby 博客站点,展示 GraphQL 数据查询、静态生成和页面路由。
完整代码
项目初始化
gatsby new my-blog
cd my-blog
npm run develop
首页 src/pages/index.js
import * as React from "react";
import { graphql, Link } from "gatsby";
export const query = graphql`
query IndexPageQuery {
allMdx(sort: { frontmatter: { date: DESC } }) {
nodes {
id
frontmatter {
title
date(formatString: "YYYY-MM-DD")
description
}
fields { slug }
}
}
site {
siteMetadata {
title
description
}
}
}
`;
const IndexPage = ({ data }) => {
const posts = data.allMdx.nodes;
const { title: siteTitle, description } = data.site.siteMetadata;
return (
<main style={mainStyle}>
<h1>{siteTitle}</h1>
<p style={{ color: "#555" }}>{description}</p>
<h2>📝 最新文章</h2>
<ul style={{ listStyle: "none", padding: 0 }}>
{posts.map((post) => (
<li key={post.id} style={cardStyle}>
<Link to={post.fields.slug} style={{ textDecoration: "none", color: "#333" }}>
<h3 style={{ margin: 0 }}>{post.frontmatter.title}</h3>
<p style={{ color: "#666", fontSize: "0.9rem" }}>{post.frontmatter.description}</p>
<small style={{ color: "#999" }}>{post.frontmatter.date}</small>
</Link>
</li>
))}
</ul>
</main>
);
};
export default IndexPage;
const mainStyle = {
maxWidth: 680, margin: "40px auto", padding: "0 16px",
fontFamily: "Georgia, serif",
};
const cardStyle = {
padding: "20px 0", borderBottom: "1px solid #eee",
};
Gatsby 配置 gatsby-config.js
module.exports = {
siteMetadata: {
title: "我的技术博客",
description: "用 Gatsby 构建的静态博客",
siteUrl: "https://example.com",
},
plugins: [
"gatsby-plugin-image",
"gatsby-plugin-sharp",
{
resolve: "gatsby-source-filesystem",
options: { name: "posts", path: `${__dirname}/content/posts/` },
},
{
resolve: "gatsby-plugin-mdx",
options: { extensions: [".mdx", ".md"] },
},
],
};
文章模板 src/templates/blog-post.js
import * as React from "react";
import { graphql, Link } from "gatsby";
import { MDXRenderer } from "gatsby-plugin-mdx";
export const query = graphql`
query BlogPostQuery($slug: String!) {
mdx(fields: { slug: { eq: $slug } }) {
frontmatter {
title
date(formatString: "YYYY年MM月DD日")
description
}
body
}
}
`;
const BlogPost = ({ data }) => {
const { frontmatter, body } = data.mdx;
return (
<main style={{ maxWidth: 720, margin: "40px auto", padding: "0 16px" }}>
<Link to="/" style={{ color: "#6366f1" }}>← 返回首页</Link>
<h1>{frontmatter.title}</h1>
<p style={{ color: "#888" }}>{frontmatter.date}</p>
<article>
<MDXRenderer>{body}</MDXRenderer>
</article>
</main>
);
};
export default BlogPost;
示例 MDX 文章 content/posts/hello-world.mdx
---
title: "我的第一篇博客"
date: 2024-01-15
description: "使用 Gatsby 和 MDX 写博客就是这么简单"
---
# 你好,世界!
Gatsby 让静态博客变得简单而强大。
- ✅ **Markdown/MDX** 编写内容
- ✅ **GraphQL** 统一数据层
- ✅ **自动优化** 图片和性能
运行步骤
npm run develop
npm run build
npm run serve
预期输出
Gatsby GraphQL 数据页
目标
展示 Gatsby 核心模式:通过 GraphQL 查询 siteMetadata 和文件数据,在页面中渲染。这是 Gatsby 最典型的开发模式。
完整代码
1. gatsby-config.js
module.exports = {
siteMetadata: {
title: '毕设作品集',
description: '展示我的毕业设计项目',
author: '张三',
},
plugins: [
'gatsby-plugin-image',
'gatsby-plugin-sharp',
{
resolve: 'gatsby-source-filesystem',
options: { name: 'projects', path: `${__dirname}/src/data/` },
},
'gatsby-transformer-json',
],
};
2. src/data/projects.json
[
{
"name": "校园3D导览",
"tech": "Three.js + Vue",
"description": "基于WebGL的校园建筑3D展示与导航系统",
"stars": 5
},
{
"name": "智能课表助手",
"tech": "React + Node.js",
"description": "自动排课冲突检测与可视化课程表",
"stars": 4
},
{
"name": "宿舍报修平台",
"tech": "Angular + Spring Boot",
"description": "在线报修工单管理与进度跟踪系统",
"stars": 4
}
]
3. src/pages/index.js
import * as React from 'react';
import { graphql } from 'gatsby';
const IndexPage = ({ data }) => {
const { title, description, author } = data.site.siteMetadata;
const projects = data.allProjectsJson.nodes;
return (
<main style={{ fontFamily: 'system-ui', maxWidth: 700, margin: '0 auto', padding: 20 }}>
<header style={{ textAlign: 'center', padding: '40px 0' }}>
<h1>{title}</h1>
<p style={{ color: '#666' }}>{description}</p>
<small>by {author}</small>
</header>
<h2>📂 项目列表 ({projects.length})</h2>
<div style={{ display: 'grid', gap: 16 }}>
{projects.map((p, i) => (
<div
key={i}
style={{
background: 'white',
padding: 20,
borderRadius: 12,
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
borderLeft: `4px solid ${p.stars >= 5 ? '#f59e0b' : '#3b82f6'}`,
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<h3 style={{ margin: 0 }}>{p.name}</h3>
<span>{'⭐'.repeat(p.stars)}</span>
</div>
<p style={{ color: '#666', fontSize: '0.9em' }}>{p.tech}</p>
<p>{p.description}</p>
</div>
))}
</div>
</main>
);
};
export const query = graphql`
query IndexPageQuery {
site {
siteMetadata {
title
description
author
}
}
allProjectsJson {
nodes {
name
tech
description
stars
}
}
}
`;
export default IndexPage;
export const Head = () => <title>毕设作品集</title>;
运行步骤
npm install -g gatsby-cli
gatsby new gatsby-demo
cd gatsby-demo
npm install gatsby-transformer-json gatsby-source-filesystem
gatsby develop
预期输出