仓库已开源:mocusez/astro-astrofly

仅供参考,目前不保证可用性

源起

从我高三开始写博客开始(2019年末),一直都是使用Hexo作为静态博客生成器。博客主题除了入门的hexo-theme-next,就是hexo-theme-butterfly

虽然Hexo一直都能很好的满足我写博客的需求,但不得说这东西满足不了我的技术虚荣心:它并不基于TypeScript(虽然但是,Hexo直到2023年的版本7.0才正式更换为TypeScript),也没用Vite,更不谈Tailwind CSS(原子化CSS方案),Vue和React这些现代前端技术(虽然但是,这两者都很好用,但小项目我还是更倾向于Vanilla JS😛)

而如果想要自定义组件,会是一件很困难的事情——我对于Hexo的了解也仅限于可用,并不了解其中的运行方式。

而迟迟没有动手重构的原因,是因为这并不是一个能给我带来很大收益计划:

首先,自己造的轮子虽然会在打包和加载速度方面有优势,但在各个页面路由的功能的实现上还需要重新构思和实现——我真正开始熟悉前端是在我上大二的时候,为了给大创项目收尾,不得不去自己学习了微信小程序编写和Vue3,参加蓝鲸智云项目了解了Vue2,真正学习写前端的时间其实并不长。

其次,CSS样式强大,但并不好调配😆这玩意自己写写就知道,想调配出好看,且能动态适应屏幕的CSS并不是个简单的事情。Hexo这两个主题动态适应屏幕都做的不错,现在想想其实都有些不可思议。

最后,学业压力是个不可避免的麻烦😫很显然,重构博客并不能让我获得更好的绩点,大伙们都在为绩点和各类学校竞赛奔波——我也不例外🤨,重构博客只能算是个人兴趣——没人会想在本该用于玩的时间,去做一个深不见底的项目。

综上,重构博客在我本科期间就是个Impossible的工作


直到时间来到了2024年——我本科毕业了🤣忘记掉学业压力吧,那不属于现在

现在的大语言模型已经能很好的解决前两个问题:使用Github Copilot或Cursor,但凡会用大语言模型都可以做出一套样式好看的CSS,能动态适配屏幕的网页

而现在,我面临i18n的需求,方便更好的与国外同行交流,而这点上,Hexo的i18n方案怎么看都不怎么让人满意。虽然hexo-theme-butterfly官方展示页有i18n,但并没有给出相关教程样例,而网上的实现方案有些奇技淫巧,折腾那些方案,还不如另起炉灶从头做起。

而现在能进行调配的时间,也远比本科时要充足的多。

于是,博客重构的计划就被安排上了日程。

选型

既然要重构,那就一定需要做技术选型,我计划的技术指标如下

  1. 支持i18n,方便后续科研使用英语写文章
  2. 支持现代的前端打包(Vite,RSbuild等),提高首次记载速度
  3. 方便从Hexo迁移

关于是要静态页面还是动态页面,在这个问题上摇摆不定了很长时间:静态页面可以更好的利用CDN,而动态页面则可以省掉页面生成的时间。但最后的决定是:静态页面优先,如果动态页面有什么特别好用的特性也可以考虑下。

单页面应用SPA(Vue&React)

我对SPA印象不是很好🙄:当初在学习Vue的时候,在路由方面踩了很多坑。而SPA对于路由的实现我也不是很满意,能不用就不用,Pass

Nuxt3

我是在大二(2022年)接触到Nuxt3,Vue + SSR的特性对我而言确实挺吸引人的,虽然教程很多,但没有一个很好的博客模板,网上也搜不到能有效支持很i18n的博客样例,Pass

VitePress

VitePress也是我一直关注的项目,是VuePress的替代品,Vue + SSG的特性也不错,文档还是和Vue一样的给力😘。

但2024年3月才正式1.0发布,这意味着重构时,网上搜不到什么好的博客模板,虽然官方支持i18n,但是没看到最佳实践样例,还是Pass

Next.js

React的SSR方案,实习的时候用Next.js 14搓了一个Demo,从页面效果上感觉还不错: Tiqqun-demo

Next.js生态十分丰富,而且有很多从Markdown转为SSR的样例,网上有不少i18n的实现样例(甚至支持Tailwind)

tailwind-nextjs-starter-blog-i18n

我不太满意的地方,在于这个框架有些臃肿,在实习时因为其浏览器缓存的问题闹出过乌龙,有点掉印象分😅

如果没有Astro,我肯定会选则Next.js

Astro

在逛V2EX的时候意外发现不少V友在推荐这个,而网上也有不少人从Hexo迁移到Astro,教程众多,而且体验下来都还不错。有很多实现i18n的教程和模板。

而在Github上,我搜到了 HsuBlog,这个方案我很满意——但似乎没适配Astro V4😅那个模板我死活用不了

相比较于一众Vue和React方案,Astro支持Vanilla JS直接进行开发——也就是说,我可以直接复用Hexo的代码,不需要花时间去处理Hexo与Vue或React的编程逻辑转换。这可太棒了🤩

而该有的RSS生成,SiteMap生成,Astro也能有效处理

如果想写Vue或React,也可以通过Astro Island进行支持

TypeScript也是个头疼的问题,但Astro V4可以默认设置不开Strict😋开发所需的心智负担可以下降一个层级

Astro既可以SSG,如果有必要的话也可以转为SSR,也就如果后续博客页面众多,编译时间太长的话,也可以自己写一个后端实现SSR。

网友用Astro做的组件,效果看起来很Nice:Custom Astro Component Sample

上手容易,支持Vite打包,后续发展潜力巨大,完美,就用它了!🥰

开发记录

Astro,启动!😆

pnpm create astro@latest
pnpm astro add vue #如果想要Vue可以加上
pnpm add @astrojs/rss

开发计划如下:

使用hexo-theme-butterfly 5.1.0作为样板进行开发

  1. hexo-theme-butterfly使用stylus作为CSS方案,这一部分照单全收
  2. 保留hexo-theme-butterfly的网页结构

第一个需要解决的问题是:如何从hexo-theme-butterfly的pug转为astro

虽然有热心网友在2024年4月提出了在Astro使用Pug的Proposal,2021年就有了相关RFC,但很遗憾并没有开发人员进行后续跟进

Add first-class support for Pug in .astro files

RFC: Add first-class support for Pug in .astro files

对于这个问题,我的解决方案是:使用Github Copilot对Pug进行转换

就结果而言,转换的效果还不错,绝大部分代码都可以完成转换,涉及到读取Hexo相关的内容则需要自己去适应调配

image-20241227110529912

Post生成

通过Collection API将Markdown导入Astro Collection,Astro会读取Markdown的frontmatter进行下一步生成

Astro V5使用了新的Collection API,具体操作记录参考:refactor: upgrade to Astro V5

代码显示优化

增加 行数显示 和 代码一键复制

如果没错的话,安装完astro-expressive-code后,应该会默认接管Shiki插件的工作

pnpm add -D astro-expressive-code @expressive-code/plugin-collapsible-sections @expressive-code/plugin-frames @expressive-code/plugin-line-numbers

由于astro-expressive-code目前(2024.12.28)还不支持LangAlias参数传递 #278 ,只能先暂时放弃,使用Astro自带的Shiki进行渲染

2025.1.10更新的0.39.0版本astro-expressive-code现已支持LangAlias参数传递

本博客已更新相关样式:commit

如果要使用Astro自带的Shiki添加行号的话,可以参考下面两个链接:

Adding Line Numbers to Astro’s Syntax Highlighting Using CSS

Line numbers

如果要增加非Shiki列表语言选项的内容,可以参考我写的另外一篇文章

如何给自己的博客添加MLIR和LLVM IR语法高亮

文章目录(TOC)

我目前的方案是Claude3.5生成的,但感觉不太聪明,有计划的话可以试试这些方案:

Astro博客构建之TOC文章目录

Astro文章搜索,创建简单的搜索组件

评论系统(Waline)

由于hexo-theme-butterfly默认已经预留好了位置,插入过程比预想当中的要顺利不少:

src/layout/additional-js.astro

<script type="module">
import { init } from 'https://unpkg.com/@waline/client@v3/dist/waline.js';
(() => {
init({
el: '#waline-wrap',
serverURL: "${serverURL}",
pageview: true,
dark: 'html[data-theme="dark"]',
path: window.location.pathname,
comment: true,
});
})();
</script>

对于旧的评论,需要去数据库手动改评论的URL,确实没有更好的办法😅

顺带升级了下Waline的服务端,从V2升级到V3,过程非常丝滑😋

但就感觉这并不是一个很好的解决方案,可能后续会改进

搜索系统(待完成)

MeiliSearch方案:Astro整合自部署 MeiliSearch

Astro简易方案: Astro文章搜索,创建简单的搜索组件

插曲

当时做选型的时候发现了这个Hexo主题支持Vite打包:hexo-theme-aurora

就是效果感觉过于Fancy😂而且当时已经下定决心要重构了,不然还是可以考虑一下的

在写这篇文章的时候,发现之前友链里的网友也将原本的Hexo转为了Astro,并且开源了他的模板:astro-antares

看起来还不错😁感兴趣的话,可以去试试

更新至Astro V5

我是10月30日那一周开始重构的,那时Astro V5还未稳定,当12月26日补齐TOC和Waline评论系统的时候,Astro V5已经正式发布了(2024.12.3),那确实也没有理由不更新

pnpm dlx @astrojs/upgrade

参考文档:Upgrade to Astro v5

特性:

Astro v5.0 upgrades to Vite v6.0 as the development server and production bundler.

好耶😆

升级时遇到了很多麻烦,很多2019-2020的老博客Zod校验不过,把老文件改了后顺利升级了

refactor: upgrade to Astro V5

要格式校验的话,那我去写Rust不好么😅我就写个简单应用还要遵守那么多规范

结语

整个重构流程大约一周的时间,使用hexo-theme-butterfly的CSS使我省去了纠结CSS的时间

效果而言,只能算够用,感觉还差点意思:还有很多hexo-theme-butterfly原有的特性并没有实现

对于这种情况,我只能说,以后有时间和兴趣的话,再慢慢补吧😜。