Aug 7, 2021 / Blog

博客重构:2021 / 第一章

该来的还是来了

去年的八月份我把博客从 WordPress 转移到了 Hugo,同时开源了当时写的主题。一年过去,文章只写了四篇,不愧是我

作为一个折腾博主,博客的主要还是我的前端实验场。经常冒出把博客从 Hugo 转移到其他平台的想法,不过都因为学业原因搁置了。这次暑假有机会一一实验,也就有了这篇文章。

初试 Jamstack:Gatsby

Jamstack 这个新的概念这两年在国外被炒的很火,其中最有名的应该就是基于 React 的 Gatsby 了。背后的原因我觉得和它丰富的生态有关:很多功能都能在它的插件市场找到相应的实现,不需要自己去写代码。使用的技术栈本身也很有热度:React + GraphQL。

按照官方的新手教程部署后,我发现它的编译速度真的好慢,只是几个简单的页面就要花费最少一分钟,这还是官方的 Gatsby Cloud。但也有可能是为了推销他们的付费套餐提供的增量编译(Incremental Build),所以特意降低了免费版的体验。隔壁的 Vercel 倒是快了不少,可以在 40 秒左右完成编译和部署。编译后的站点访问体验倒是非常不错:内联首屏关键 CSS (Critical CSS),图片懒加载,按路由拆分脚本… 等等前端优化技术都自带了。

由于是基于 Node.js 的生成器,node_modules 文件夹自然是少不了。但 Gatsby 的是格外的大,我都还没搭建好就已经占了快 400MB 的空间:

我是挺想体验下在 Gatsby 上写主题,尝试 CSS Modules 这类新功能。可每次说服自己后,一上手就会被它的速度给劝退。启动开发服务器(npm run dev)就要花费不少时间,而且修改配置文件(gatsby-*.js)在很多情况下是需要重启服务器的。一开始因为需要修改路由,但这些配置文件都不支持 TypeScript,所以浪费我了很多时间在猜内置函数的类型和参数上。😓

Gatsby 使用的 GraphQL 我本以为会很好上手,结果反而把我弄的更头疼:Gatsby 限制每个页面只能有一个 GraphQL 查询,我想先查询当前文章的数据,再去获取它所在分类的数据。听起来很简单的需求,但我折腾半天没搞懂如何在同一个查询里面完成。

在前面提到过它的插件市场很丰富,但几个月前 Gatsby 推出了 V3 版本,有些插件已经无法兼容最新版本(不再更新),只能找替代品,或者自己动手修。我真的不希望我今年配置好的博客,等明年暑假再拾起时,一个更新就给搞挂了。

Next.js

放弃 Gatsby 后我又把目光转向了隔壁的 Next.js(也尝试了下 Gridsome,但感觉和 Gatsby 差不多,只是把 React 换成了 Vue)。我之前一直以为 Next.js 是拿来搞 React SSR 的,看了下版本记录似乎是在两年前的 V9 版本中加入了静态站点生成的功能。

不同于 Gatsby,Next.js 没有那么完备的插件市场,大部分的功能,就连生成博客的文章数据都需要你自己从头开始编写。但编译和启动速度比 Gatsby 快了不少,而且还有官方的 TypeScript 支持,写代码终于不用靠猜了 😭。

花了点时间编写了脚本来索引硬盘里的文章,然后发现了一个很坑的问题:文章附件需要放在 public 文件夹下才可以被访问。我博客为了使用 Hugo 的 Page Bundle 功能,文章采用了以下结构存放:

├───content
│   └───post
│       ├───2021
│       │   └───08
│       │       └───文章文件夹
│       │           ├───index.md
│       │           └───图片.jpg

要解决这个问题,要么把 content 文件夹移动到 public 目录下,要么把图片和文章分开存放(但这样在大部分编辑器里面就不能正常预览图片),两者我都不是很喜欢,所以 Next.js 也被我淘汰了 😓

回到 Hugo

这一趟折腾下来也学到了不少新的知识,冷静思考过后发现还是 Hugo 这类“旧时代”的生成器最适合我的博客:安装起来简单,生成速度也快,自己也有使用经验。Gatsby 和 Next.js 都很好,但不太符合我当下的需求。或许未来某一天我又会一时兴起再尝试转移过去 😌。

(我觉得我很有可能等到 Svelte Kit 稳定后尝试用它来搞个博客生成器)

新个人主页

二月份的时候在网上看到了 Vite 这个新构建工具,当时就冒出了重写个人主页想法(四年多没换了)。那就就搞个和博客主题一样的卡片式风格好了:

因为当时没什么时间,所以只是用 Figma 画了图,没去写代码。后来在三月底的圣周假期抽空去实现了下,还体验了 Windi CSSSvelte,两个都是前端娱乐圈的新起之秀。

我为什么要提这个呢,因为这篇文章的下一章就要扯到评论系统的重构过程了😂,而它的前端最后采用的便是上面提到的 Vite + Svelte + Windi CSS 组合。

回到正题,新的个人主页一开始还是很讨我喜欢的。但后来发现这玩意也太花哨了,点进去完全不知道要看哪里好。有些部件也毫无意义,例如最新的推文显示,访客完全可以自己点进 Twitter 看 🤷‍♂️(更别提我很多推文都有点丧,不是很雅观)

于是就开始思考如何做减法。参考了 Twitter 上的两位大佬(Spencer Woo & 熊猫小A)的个人主页后我意识到其实没必要搞那么复杂,就放个简单的个人介绍和一些链接就足够了。

于是便有了第三版的个人主页设计:

一开始使用了和上一个版本一样的前端框架组合。但后来因为开始学习 Next.js 就用它重写了一遍(复制粘贴),也就是目前上线的这个版本。当然,这么简单的页面上框架完全是在大材小用,也会加载一堆完全用不到的脚本。不过我也懒得去改了,能跑就行 😂。

其实还有一个原因:只用 Svelte 的话禁用 JS 后页面就渲染不出来了,可以用 Svelte Kit 来解决 (SSR),但在写文章的这一刻(八月六号)还处于 Beta 阶段,所以就不折腾了。

新主题

来都来了,新主题自然是少不了了。

这个简单的设计风格也奠定了接下来博客的主题方向。去年的主题我还是很喜欢的,但看久了就感觉有点累了,所以这次就换个风格好了。

说到做减法,新主题去除了主页的文章分页,默认显示最新的五篇文章。博客目前一共就二十多篇文章,分页也没什么意义,还没直接去归档页面找来的快。

头部标题的镂空字体的背景是文章的特色图片。我有想过把图片直接展示出来,但多次尝试后对效果还不是很满意,就暂时搁置了。我最喜欢的版本是下面这个,但非常挑背景图:

Hugo 内置的 Sass 编译器是 LibSass,在去年的十月份已经被官方标记为已弃用,并推荐下一代的 Dart Sass。Hugo 也支持使用 Dart Sass文档),只不过没有内置,需要自己下载二进制并加载到环境变量里。

那既然要追求刺激那就贯彻到底咯。于是我就在新主题用上了它。其实我平常也只用到嵌套和 @mixin 这些基本的功能,但这次新加入的 @use 关键词倒是很有用:

The @use rule loads mixins, functions, and variables from other Sass stylesheets, and combines CSS from multiple stylesheets together. Stylesheets loaded by @use are called “modules”. Sass also provides built-in modules full of useful functions.

[…] Any styles loaded this way will be included exactly once in the compiled CSS output, no matter how many times those styles are loaded.

之前我拆分 Sass 模块后都是使用 @import 来引入。但假设有四个模块 ABCD,A 和 B 使用 @import 引入了 C,最后 D 又加载了 A 和 B,那最后编译出的 D.css 就会出现两次 C 模块。而使用 @use 就可以避免这个问题。除此之外引入的模块也不再默认挂载到全局。

(去年写的主题就遇到过这个重复引入的问题:fix(scss): remove unnecessary import (#146)

隐私 & 统计服务

最后,很久以前就想把网站的 Google Analytics 换掉,主要是因为它太重了,桌面版后台加载速度好慢,收集的数据大部分我也用不上。根据 GDPR 还需要在页面上挂出相应的隐私政策。

Privacy Focused Analytics 这个网站上陈列了一些不需要使用 Cookie 的网页统计工具。我看中了 UmamiPlausible

Umami 搭建需要 Node.js + (MySQL / PG) 环境,甚至可以在 Vercel 这类 Serverless 平台上跑起来。相比之下 Plausible 就稍微麻烦了些,需要使用 Docker 来安装,用到了两个数据库。ClickHouse,Plausible 使用的数据库之一,不支持 Linux / ARM64,没法在 Oracle 的 ARM 机器上跑 🥲

我两个都尝试后暂时选择了 Umami,因为搭建起来比较简单些。两者的后台界面都非常简洁,各自的官网上都有在线 Demo,感兴趣的可以去体验下。资源占用方面,程序本身,不算上数据库,在 PM2 里面显示使用了 ~60MB 的 RAM.

上线两天后发现统计服务挺吃数据库的,一晚上能刷出一千行的记录,有在考虑要不要使用托管服务,自己没有数据库管理的经验。

打算博客重构结束后搞个页面,列出博客所用到的第三方服务,以及相关的隐私政策。目前博客使用到的服务有:

  • Vercel
  • Cloudflare
  • Google reCAPTCHA (只在发表评论时加载)
  • Cloudinary
  • Umami

最后

快一年多没写博客了,感觉有点陌生了。写这篇文章的时候多么希望自己可以就此静下心来,好好写写日常博文,少折腾(这种 Flag 我感觉我每年都立过 🥲)。这一年其实也有很多值得记录的日常,大部分因为懒或是没空就干脆不写,或是直接发到推上。希望接下来的一年可以多写点文章吧。

这篇文章就到此结束了。下一章 (应该也是最后一章)会谈谈评论系统的重构。目前上线的评论系统还有很多体验问题,但最基本的提交应该能用(I hope so.)

Cover image by Halacious on Unsplash

CC BY-NC-SA 4.0