在去年年底的时候,在外观和功能没有明显变化的情况下,将本博客的技术栈从 Hexo 改为了 Gatsby。没错就是自己重写了一份。随后也为 @Fin 使用 Gatsby 重写了博客。既然是差不多的事情就放一起写了吧。
其实重写博客的想法早已有之,在之前自己写 Hexo 主题的时候,我就有感于 Hexo 的弊端。作为一个使用者,你只是正常的写 Markdown 然后发布,用什么都无所谓。但开发 Hexo 主题使用的是各类模板,让人梦回 JSP 时代。一方面编辑器的支持不太好,写代码没那么顺手;另一方面,在前端技术飞速发展的现代,模板式的写法确实显得落了一截,很难享受到很多前端发展的最新成果。这也是为什么之前我列了很多 TODO 项,因为一些复杂的功能开发起来实在麻烦,使我没动力继续下去了。
之前写主题时,我就设想了许多动态化的功能。我理想中的博客已经不仅仅是一系列 Markdown 文章的集合,而是逐渐向一个应用化的方向发展。去年学会了 React 与 Vue 两大框架,就自然而然地与前端应用产生了联系。
我设想中的博客网站基于 React 或 Vue 技术栈。将一个单页应用用于博客并不适合,因为会有 SEO 的问题,但作为我的个人空间,我并不在乎它能否被搜索引擎找到,甚至想避世隐居。除了 Markdown 以外,博客的内容还可能来自其他很多数据源,因此将会有一个数据中间层,将所有数据源转变为 JSON 之类的通用数据格式。而前端页面在使用数据时,就可以像普通网站那样,通过 API 把数据请求回来。
我甚至都开始设计接口,准备造轮子了。不过在搜索类似的做法时,我找到了 JAMStack 技术栈。它不仅能够完全符合我的需求,而且也解决了 SEO 的问题。它甚至有自己的官网。初次看到它的理念,就像遇到了一位老朋友一样,令我兴奋不已。我并不想把这篇文章变成 JAMStack 的介绍帖,因为它的官网已经写的足够好了,无需画蛇添足,感兴趣的朋友可以移步它的官网进一步阅读。
在 JAMStack 的官网上列举了许多具体实现的框架(当然,Hexo 作为静态网站生成器,也是其中的一员)。结合 React + SSG 的标签,我们很容易将目光放在当今最为流行的框架之一 —— Gatsby 之上。在对比了其他定位类似的框架之后,我发现它不仅拥有上述 JAMStack 提到的所有优点,而且还有一个最大的特点,即 GraphQL 中间层,可以将任何来源的数据源统一转换,在前端代码中利用 GraphQL 做编译期查询。简直与我的想法不谋而合!
除此之外,Gatsby 还提供了其他人性化的功能。例如内置的 Link 组件,在首次加载页面后即可预加载其他页面,用户跳转时无需刷新整个页面,得到 SPA 的丝滑体验。还有 gatsby-image 插件对图片的处理,为你自动压缩、优化,根据浏览器环境选择合适的图片格式与图片大小进行加载,同时还能拥有渐进式加载的过程。不仅省去了你之前自己处理图片、上传图床的功夫,还大大提升了用户浏览时的体验。
Gatsby 上手难度并不高,唯一蛋疼的是在国内安装颇费一番功夫。虽然 npm 可以换国内源,但是底层需要一些图片处理的能力,安装过程会直接从 GitHub 原始地址下载,还有 node-gyp 之类的配置等需要安装,要么有个好的梯子,要么需要自己额外处理下。开发过程倒是轻松愉快,借助 React 的庞大生态,可以轻松实现之前做的很蛋疼的功能。在之前的开发记录最后,我留下了一堆 TODO 项,都是因为做起来很麻烦的,这次也都一口气实现了出来。
顺便,在开发的过程中,也实现了不少副产物。在 Hexo 中有现成的评论插件,不能在 Gatsby 中使用,因此直接重写了一份。另外评论的邮件提醒功能,也调研了阿里云的邮件服务与云函数得以实现。由于它们都有每月一定的免费额度,我们就可以愉快白嫖。
Gatsby 中也没有现成的文章加密功能,为此也自己造了一个轮子,研究了一下 gatsby-remark 插件的写法,并开源发布在了 npm 。地址在 gatsby-remark-encrypt ,欢迎大家多多 star ←_← 。与 Hexo 版本的加密插件不同,它并不负责 UI 的展示,而只是专注于实现加密功能本身,提供加密后的数据源供 GraphQL 调用。当然,我在文档中也提供了简单的 Code Example 。
之后也为 @Fin 写了一份博客。虽然用的是同一套技术栈,但由于网页的布局与涉及到的功能都和自己的有不少区别,因此也接触了不少新东西,例如对 Latex 的使用、pdf 嵌入、以及一些 Gatsby 的高级 API 等。碰巧在这期间 Gatsby 也升级到了 v3 版本,主要改进了图片的使用方式,变得更为简单,遂学习之。
一个有趣的功能是全文搜索。虽然 Gatsby 生态中已经提供了一些现成的搜索插件,但是实际使用后发现它并不能支持中文分词搜索。将搜索插件所生成的索引文件打开来看后,发现所有中文的内容都默认被过滤掉了。所幸在网上找到了一篇介绍 VuePress 使用 FlexSearch 进行繁体中文搜索的文章,配合自己的调试,总算是做出了比较完美的解决方案。有时间的话后续也再深入了解一番,写篇文章。
另一个值得一提的点是,为了让自己在新的项目中有所收获,我也尝试了一番前段时间老是见人提起的 TailwindCSS 框架。我个人觉得还是值得一用的,而对这种原子 CSS 的用法也有了一些个人感想,在未来也会单独发文。或许某一天我也会用 Gatsby v3 + TailwindCSS 更新我的博客。(又给自己挖坑了(笑