为什么需要搭建个人博客?这个问题有很多答案,每个人的答案可能不太一样。就我而言,我希望的是分享我的笔记也方便自己查阅,当然这是主要原因并不是唯一原因。
之前也折腾过其他的博客系统(轻度用户),例如 WordPress、B3log/Solo。
最近发现了 Gatsby 这个基于 React 构建的网站生成器,拥有很高的可定制性让我很喜欢,所以我决定将我的博客使用 Gatsby 搭建一遍。
虽然我对于前端的了解的不是很多,我还是期望自己动手制作整个博客的页面以及样式,这大概就是越菜越爱玩吧。
所以我选定的 Starter 是 gatsby-starter-hello-world,用于学习也方便结合官方文档(中文文档)理解其基本原理。
说明项目的基本结构,方便组件的统一管理。
/src/pages
的组件会生成对应的页面。/src/templates
用于存放的模板组件,例如渲染 Markdown 文章的模板。/src/components
存放一些共用的组件。/static
放置的都是静态资源。介绍三个比较重要的文件。
/gatsby-config.js
用来配置 siteMetadata
(全局信息)和 plugins
(插件)。/gatsby-node.js
可以调用 Gatsby API 干一些自动化的工作,如:为 Markdown 文章生成自定义路径。/gatsby-browser.js
可以调用 Gatsby 浏览器 API 也可以通过该文件引入全局 CSS 文件。Gatsby 有着很多的插件帮我们节省了很多精力,这里介绍几个更多的插件需要到官网的插件库查看。
我以 gatsby-starter-hello-world 作为基础项目,扩展安装的插件如下。
npm install --save gatsby-plugin-typography react-typography typography typography-theme-fairy-gates
npm install --save gatsby-source-filesystem gatsby-transformer-remark gatsby-remark-images gatsby-plugin-sharp
npm install --save gatsby-remark-highlight-code @deckdeckgo/highlight-code
npm install --save gatsby-awesome-pagination
npm install --save gatsby-transformer-sharp gatsby-plugin-image
插件的使用流程分为几大部分。
npm install --save xxx
命令安装。/gatsby-config.js
配置相关插件。关于插件的使用流程整体上是一致的,我在这里以 Markdown 生成页面所需要的插件为例讲解一下。
涉及的核心插件有如下几个。
gatsby-source-filesystem
用于读取项目中的文件。gatsby-transformer-remark
可以将 Markdown 生成 Markdown 节点,节点用于页面的生成。gatsby-remark-images
gatsby-plugin-sharp
处理 Markdown 中的图片,否则会导致 Markdown 的图片不可用。插件的安装命令:npm install --save gatsby-source-filesystem gatsby-transformer-remark gatsby-remark-images gatsby-plugin-sharp
。
插件的相关配置是在 /gatsby-config.js
文件中。
module.exports = {
plugins: [
`gatsby-plugin-sharp`,// 配置的 sharp 插件,用于处理图片的库
{
resolve: `gatsby-source-filesystem`,// 读取项目中的文件
options: {
name: `src`,
path: `${__dirname}/src/`,// 指定文件目录
},
},
{
resolve: `gatsby-transformer-remark`,// 将 Markdown 生成 Markdown 节点
options: {
plugins: [
{
resolve: `gatsby-remark-images`,// 处理 Markdown 中的图片。相对于其他插件,该插件是给 gatsby-transformer-remark 使用的
options: {
maxWidth: 800,
},
},
],
},
},
],
}
在 /gatsby-node.js
中使用 graphql
查询所有的 Markdown,并用 Markdown 节点生成相关的页面。
const { createFilePath } = require(`gatsby-source-filesystem`)
// 自定义 Slug
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
}
}
// 创建页面
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions;
let resultBlog = await graphql(`
query {
allMarkdownRemark {
edges {
node {
id,
fields {
slug
}
}
}
}
}
`);
// Create blog pages
resultBlog.data.allMarkdownRemark.edges.forEach(({ node }) => {
console.log("Create page: " + node.fields.slug);
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/blog-post.js`),
context: {
slug: node.fields.slug,
},
})
})
}
文件 /src/templates/blog-post.js
是博客对应的模板文件。文章篇幅受限,具体的使用可以查看 Gatsby 中文教程。
贴出模板文件示例。
import React from "react"
import { graphql } from "gatsby"
// Init
export const query = graphql`
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title,
author,
date
}
}
}
`;
const blogPost = ({ data }) => {
const post = data.markdownRemark
return (
<div>
<strong>{post.frontmatter.title}</strong>
<div>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</div>
</div>
)
};
export default blogPost;
阅读官方文档更容易学习相关知识,Gatsby 的引导教程相对简单,按着教程入门还是没问题的。
完成了从 Markdown 到页面的转换后,其实核心功能已经完成,余下的就是不断丰富博客系统了。
这里举几个例子,也是丰富博客的方向,我的目的是生成静态博客。
以该文章的最终效果作为示例(样式还没做修正)。