tl;dr: 我的个人网站已开源
动机
在阅读这个博客之后,我决定做一个自己 host 的博客站点。
一般有 2 种方法制作博客站点:使用所见即所得的博客制作工具如 WordPress 或从零开始 写网页。
我决定使用一个标准的开发框架:Gatsby,因为我能。
背景
Gatsby是一个基于 React 的多页网站制作框架。它的技术栈如下图所示:
因此它的前置技术包括 HTML,CSS,JS,TS 和 React。
挑战
在开始这个项目之前,我对 Gatsby 没有任何了解。因此我学习 Gatsby 完成这个项目的过 程对任何想学习 Gatsby 的新手也有参考价值。
生成静态网站
因为我在上一个项目使用过 Next.js ,我对服务器渲染(SSR)有充分的了解。但是这个经 验对 Gatsby 完全无效,因为它是一个静态网站生成器(SSG)。这种基本的差异导致我在 学习的过程中遇到很多坑,因此我记录了它们的区别。
SSR | SSG |
---|---|
运行时可以跑服务端代码 | 运行时没有服务端 |
部署时必须搭配服务端 | 只能部署静态的 html/css/...文件 |
实时获取数据 | 数据变化需要重新编译才能生效 |
那么应该如何使用 SSG 构建一个完善的网站?很显然如果有一个自定义服务器,数据和网 页可以放在一起,例如文章数据以 JSON 或 Markdown 格式存储,同时也可以把网页存储在 服务器的另一个目录下。但是 Gatsby 要求所有数据都要在构建时融入网页。
使用 GraphQL 获取数据
在构建时,Gatsby 会启动一个提供所有数据的服务器,网页则可以向此服务器发起请求以 获取它需要的部分数据。此过程仅在构建时发生。
本地化
我的博客必须要服务于英语和中文的读者,因此我的博客必须支持中英双语。这也是我决定 自建博客时的主要考虑因素之一,因为现有的博客平台没有一个在中外都有强大的影响力。
在实现的层面,网络上有很多工具和案例以供参考。
Gatsby Plugin I18next
在本地化大量独立字符串时,i18next是一个完美的解决方案,但在细节上还有一 些坑。
本地化的支持来源与一个由 context 提供的 i18next 实例,因此必须将所有的页面和组件 都包在这个 context 的 provider 里面 。这个博客提供了一 个优雅的实现。
手动翻译
对于另一些内容很密集的页面,例如博客,我倾向于用 markdown 编辑它们,但 i18next 不支持 markdown。因此我的路子是手动生成博客页面。
Heading 锚
markdown 有个很有用的增强,就是 heading 锚。而且它是 TOC 的必要前提。但
是gatsby-plugin-mdx
默认不提供这个支持。
基于此文,添加这个特性非常简单。
部署
最后一个问题是如何托管这个站点。大体上有 2 种方法:
- 在自管服务器上托管
- 在公有云上托管
我恰好知道两个免费的托管服务:Github Pages 和 Cloudflare Pages。后一个需要注册一 个个人域名。