此前,大约有一年半没有更新博客程序,今年又开始修修补补。终于最近几个月,开始使用 Astro 进行重构,只增加了为数不多的几个功能,其他方面的几乎完全保留。

我希望能够实现 Grav 那样的内容结构,直接生成静态站点,剥离交互功能。上一个版本使用 SvelteKit,基础功能大多已经实现。想继续重构时,感觉这个纯内容发布系统似乎更适合使用 Astro。于是一直拖延了很久。

最早我计划逐步地迁移到 Astro,哪怕是以 Astro 岛的形式先对 Svelte 进行包装,再逐步替换 Svelte 组件。Codex 重置次数还有剩,索性就直接让 Codex 从头开工。

Codex 的三次开发

第一次,我直接让 Codex 直接将 SvelteKit 项目迁移到 Astro。进度很快,但是代码质量与表现完全不符合预期。无论骂多少次,Codex 都在自以为是地重新搞发明。最终的产出与原来的程序无论是在代码逻辑还是表现上,都是两套东西。

第二次,开始给更多的限制,一定要保证 1:1 像素级复刻。Codex 开始很小心,甚至走上了使用 Astro 岛包装 Svelte 的路线。项目磕磕绊绊,随时都会烂尾炸掉的样子。

第三次,放弃了直接迁移,先重头开始构建了一个完整的 Astro 站点,然后逐步抽出引擎模块、主题模块,重构内容结构。最后才从原 press 项目中吸收功能,原有的 Typescript 与 CSS 仅做少许修改,逐个落实在引擎和主题上。最终页面表现与原项目几乎没有差别。

全新的博客程序

主体本质上是一个静态站点生成器。主题负责所有页面上的表现,就和 Grav / WordPress 的主题一样,只关心如何把数据渲染成网页。当基于一个现有主题搭建新站点时,并不需要考虑任何框架相关的东西,只需要关注内容结构即可。配置、数据、页面、文件,整理好之后,就能发布新站点。

不过,前一个版本设计了一个奇葩的多语言实现,使用默认无 locale 的 url 来提供自动切换内容语言的功能。这在生成器生成的纯静态站点中是无法实现的。于是又实现了一个动态的多语言路由。

最终形态是,全站数据和页面都是静态的,但是语言路由负责处理语言和请求转发。这种模式也很适合部署在 Cloudflare Worker 之上。

ServerRequestCookie or Accept-Language Headerzh-CN or zh-SGzh-TWen or otherMatch LocaleRoutezh-Hanszh-HantenBrowser

另从原项目中剥离出了交互功能,需要额外部署。通过交互服务提供的接口,实现评论与引用。这不是 Disqus 之类的那种外挂第三方评论。最大的不同是,不是那种网页挂一段脚本,动态加载出评论。而是只提供接口管理,最终的评论数据保存在本地站点内容之中,最终也会渲染成静态页面。

Interact ServiceBrowserBuilderInteract ServiceBrowserBuilderHTML with CommentsAdd New CommentsNewest CommentsNew Comments since Last Sync

一个新功能

此前,讨论过如何证明自己是原创作者。时隔一年,终于落实了一项措施。尽管我尚未被抄袭,不过能防范于未然也是极好的。

文章每个修订版,都应当包含作者声明、数字签名与可信时间戳。所有证据提供打包下载,可以离线验证。

总结

新版的访问体验,除了免页面刷新的骨架屏,几乎没有任何缺失。Astro + Cloudflare,真香!