博客重构记录:从手写到拥抱框架
从很久之前开始,我就萌生了将博客重构一下的计划,但是一直没有实施。
我的博客的历史大抵要追溯到我的高一。总体上有这样几个阶段:
- luogu题解区;
- 手写 html;
- 文章页的html切换为使用脚本生成,其中使用 pandoc 将 Markdown 转换为 html;
- 切换到框架。这里我最终选择了 Vitepress。
其中,前 3 条都是在高中时期完成,但是从 3 切换到 4 却是迟迟搁置。
一直到了前些日子,需要搭建一个学术主页,恰好有了契机,于是顺便将整个网站重构了一番。
为什么选择 Vitepress?
这个其实和我个人经历强相关。正好借这个机会分享一下好了。
在高中毕业时,我对前端的理解程度其实只有 HTML, CSS, JS 这么多。
在大一上的学术写作课上,一些数据的处理需要用到机器人爬虫之类的小工具,因此接触了 typescript。 同期的程序设计课的最后一个大作业 Bookstore 有前端的加分任务,我当时仍然不会任何一个前端框架,了解到了有一个前后端通信的方式是 WebSocket,于是用 C++ 手搓了一个后端,在TCP上传输 WebSocket,前端甚至都不能成为GUI, 只是将命令行搬到了网页上。
寒假时阅读了一些 ACM OnlineJudge 的源码。我们的这个 OJ 使用的是 Flask,语法已经很像 Vue 了,也是类似在 html 里使用 {{ data }} 嵌入数据。
大一下时的数据结构大作业 TicketSystem 也有前端加分。但是总归不能再用控制台去诓骗助教同志。当时大概看了不少知乎等,最终决定了使用vue来写,同时使用了 ElementUI。
再后来,参加了一个开发网站的项目。在这个项目中,我们也选择使用 Vue 来实现前端。这里不得不提到,我舍友本来复杂的是LLM处理部分,但是后面被我拉来写前端了(笑)。我则是主要负责后端部分,一开始使用的是 Flask, 后面切换到了 FastAPI。这部分内容可以参考我之前写的一篇 FastAPI 折腾记录。
因为上述的经历,我在选择重构博客的框架时,也就倾向于使用 Vue 相关的技术。 我也考虑过要不要自己从头写一个vue项目,但是由于不太熟悉SSR技术,还是没有选择。 因此,我先了解到了 Vuepress, 但是它有一些我实在忍受不了的不足。 后来了解到了 Vitepress, 最终决定选择了 Vitepress。 但是 Vitepress 也有它的一些很遗憾的问题。这些我稍后会详述。
迁移的细节
全新的学术主页
在写这一页时,最能体会到 vue 的美妙。因为我可以写一个 Vue 组件,将样式逻辑和内容完全分离。内容部分只需要使用 Markdown+SimpleHtml。
完全自主的 Theme
好吧。其实只是把之前博客的样式重新复现了一遍。
这也是我个人的一点小小固执吧,总是希望自己对这个网站有完全的理解和控制。 因此虽然直接使用框架的默认主题或者其他人的主题很方便,但我还是花了些时间,从0写了一个新主题,而不是像网上可以搜到的大多数主题一样扩展默认主题。
当然并不是完全一模一样。我还是顺手加了一些图标之类的优化。
我觉得从之前纯 CSS 切换到现在的 Vue, 在样式这个方面最大的好处是代码更清晰,对应关系更明确了。而之前样式和HTML分隔在不同文件,不容易快速对应起来。
支持 Feed.xml
这个功能我一直很眼红,我的一些同学的博客就有这个功能。它给我带来了很大的便利。我只需要将订阅链接填入比如 Thunderbird 的软件,软件定时轮询,当同学更新时,软件就会发现并告诉我。 其实目前还没实现,但我已知这个可以做,大抵就在近几天实现。
一些吐槽
也许吐槽的欲望才是支撑我写这一篇博客的最大动力。 真的深刻体会到,天下框架一般黑,各有各的坑。。
Vuepress
Vuepress整体上还是很灵活的,有插件支持等等。
但是怎么连 cleanURL 都做不到? 某个古早版本还可以通过插件时间,但是这个插件后面也用不了了。
现在似乎也没有什么人继续维护,相关的 Issue/PR 搁置着。
我尝试通过插件hack,但没有成功。
Vitepress
Vitepress 乍一看文档,支持很多有意思的功能,比如路由rewrite, 原生的cleanURL支持。
但是当我开始尝试写自己的主题... Vitepress 提供的接口还是太精简了一些。
当我想写一个文章列表页面,需要获得所有文章的信息。于是我想要一个能获得所有页面的meta信息的接口。可惜并没有。 好在有一些类似的接口,可以扫描文件夹然后返回Markdown文件的信息。但是... 这个数据可能跟最终页面的数据是不一致的。。 因为真实的每个页面还有一些函数可能对其进行修改,但是这个接口并没有处理这些。
好在这个问题我最终通过阅读他们库中的代码,还是找到了实现方式,只是麻烦了一些。
吐槽我自己
要求太多导致的。如果我不是有那些奇奇怪怪的偏好,其实直接套别的框架就完了。
举例来说,我不希望数据公式在服务端就进行渲染,因为渲染之后是大量的 SVG 类似的内容。我希望服务器发送过去的数据就是纯粹的 LaTex 公式,然后在客户端用 js 渲染。显然没有任何框架提供了这样的设置,我只好自己来。
总结
一路探索过来,学了不少知识,也是踩了不少坑。也许什么时候有空了,可以去提个 PR 把我想要的这些feature加一加。但是不知道是什么时候了。