
图片出自TV百合动画《上伊那牡丹,酒醉身姿似百合花般》
博客搬家
我最开始自己搭个人博客的时候什么都不懂,是照着一个B站教程一步步搭建的(→ 超详细!个人博客搭建教程,低成本,零代码,手把手,WordPress ),流程也比较简单,就是虚拟主机租赁、域名购买、WordPress安装这几步而已
这种方式很快就遇到了几个严重的问题,一个是访问速度太慢,另外一个是我的存储空间快要捉襟见肘了
我完全按照视频教学流程,租了一个虚拟主机而不是云服务器,如果说租VPS是在网上租房,租虚拟主机就是在一个房间里面租了个衣柜。我只有500mb的网页存储空间——WordPress和它臃肿的插件,每篇文章里面再放几张高清图片,已经快要把这个衣柜塞满了。访问太慢的原因主要是4mbps的带宽限制,以及由于虚拟主机的多人合租性质,一个物理服务器上的所有虚拟主机共享CPU和内存,意思就是可能有很多人在同时从这个房间里面拿衣服,但是不是所有人都能第一时间站在衣柜前
实际上,用WordPress动态站方案搭建个人博客,完全是功能过剩,并且不算是现代开发者搭建博客的主流架构,这是我之后才逐渐明白的

个人博客是以文字和图片为主要载体的个人表达(可能有些博客连图片都不需要),不需要很多花里胡哨的功能,用静态站实现是最合适的
简单解释一下二者的区别
WordPress为主的动态站,实际上是把数据打散了存储到数据库里面的,Web服务器(Nginx)收到的请求,转发给PHP-FPM进程,PHP解释器进行URL解析判断访问者请求的页面,是主页还是文章等等,然后进行激烈的查询,执行php主题和html拼接,最后把拼出来的完整html交给浏览器渲染,如果用做菜打比方,后端处理每一次访问都要从头开始执行一次烧油炒菜的全套流程,这不仅耗费大量时间,而且对于个人博客来说完全没必要
VitePress的静态站实现,就是端上来预制菜,在文本编辑器里面用md语法写出来的文章,被markdown-it解析为抽象语法树,再由VitePress编译为Vue组件的渲染函数,Vite打包压缩后,生成预渲染的HTML文件,附带所需的JS和CSS资源,CDN接收到请求后直接返回静态文件,首屏加载远远快于动态站
静态站部署在Vercel上也不需要担心存储空间问题,更重要的是,Vercel部署是完全免费的
所以WordPress的工作流程其实有点花冤枉钱,搭建静态站根本不需要花租虚拟主机的钱,不过域名的钱还是得花,Vercel的URL在国内会被墙,顺带一提,域名申请有几率碰上属地与居住地不符,导致审核不通过的情况,我个人是在寒假回家期间租的,运气好没遇到什么阻碍
新家装修
新站点什么都很好,就是外观不尽人意,现有的定制化主题中,并没有非常舒适的二次元主题

南无三,二次元主题,实则美丽!
之前的架构用的是WordPress下的Sakura主题
GitHub地址 https://github.com/mashirozx/Sakura
Sakura和Sakurairo主题提供了非常全面且周到的服务,不过我基本上没用到,只是觉得很好看
我去找了一下VitePress下有没有类似的主题,很遗憾,二次元主题在极客风格站点下被评为不通过,基本上没什么萌萌的优秀主题,不过我还是找到了一个VitePress下的Sakura主题移植,
GitHub地址 https://github.com/flaribbit/vitepress-theme-sakura
这个仓库的最后一次commit是在2024年,作者flaribbit已经很久没有维护过这个项目了,而且也有很多没完全移植过来的内容,但是还是非常感谢他的贡献
我把这份源码clone到本地,然后在他的工作基础上,开始了自己的改造
轰轰烈烈的主题大改造
主题相关代码在博客文件夹根目录下的.vitepress/theme 里,由多个以.vue为后缀的SFC单文件组件共同实现
组件化思想是一种降低网页代码耦合度的方式,Vue3的组件逻辑上和编程语言里的函数有相似之处,组件各自实现负责的功能,拼装在一起完成整体界面的展示,内部代码封装,一个组件的样式和逻辑不会意外污染其他组件的内容,父与子之间通过属性传递机制实现沟通
以本主题的架构为例,Layout.vue是页面渲染的全局指挥,HTML里面的<Header />负责导航栏,而导航栏内部的实现由import Header from './Header.vue'导入Header内部的方案,就算Header写崩了,也不需要修改Layout的内容。不过如果一个SFC组件有严重错误,VitePress的构建会出错,就像函数内部的语法错误会导致编译不通过一样
事实上,这些工作的绝大部分内容是由deepseek-v4-pro和claude code实现的,所以我不会写如何实现个人风格或者如何微调CSS,只会选择我自己觉得有意思或者有价值的部分讲一讲
首页:
首页标题其实是Neta终末地的无衬线白字演出

图片来自 终末地白字,但是莫名其妙
我感觉这个还挺帅的,不过如果完全还原的话,应该只写上去两个字“博 客”
想了想好像有一种简约又直白的美
终末地中使用的字体是"HarmonyOS Sans",我觉得这个字体挺好看的,所以设置成了博客所有文字使用的默认字体
sakura主题的话,首页中间会有一个缓慢旋转的博主头像,说实话我不是很喜欢这个设计,感觉很土,我这里把头像放在导航栏了,导航栏的设计完全照搬了sakura主题的方案
文章列表:
Sakura主题里面,每次会在一个图片池里面随机抽取几张图,作为首页背景图或者文章列表的展示图
我很喜欢给每篇文章安排一个头图,大部分是取自我写这篇文章期间在看的动画,所以我把这部分内容写到了主题里面
每篇文章的.md里都有一个head,包括标题,作者,日期,封面,元素和摘要,这些内容会部分展示在文章列表和正文界面
写文章列表发现的一个问题
最开始的时候文章列表里面的封面图完全不显示,找了几次才发现这个问题:
Vite构建时会给图片文件名加一串哈希码(缓存优化),如果写的是原始路径,dev模式下还能找到,但是生产构建之后原始的路径就根本不存在了,导致本地调试看起来没问题,部署上线就显示滚木,得用import.meta.glob自动查出改名后的真实路径
//BlogList.vue — 旧代码
function coverStyle(p: PostData) {
if (!p.cover) return ''
const dir = p.href.replace(/\.html$/, '')
return `background-image: url(${base}${dir}/${p.cover})` // ← 直接拼原始路径
} //BlogList.vue — 新代码
const imageMap = import.meta.glob('/posts/**/images/*.{png,jpg,webp}', {
eager: true, query: '?url', import: 'default'
})
function coverStyle(p: PostData) {
if (!p.cover) return ''
const dir = p.href.replace(/\.html$/, '')
const url = imageMap[`/${dir}/${p.cover}`] // ← 从 glob map 查出带 hash 的真实 URL
if (url) return `background-image: url(${url})`
return ''
}文章展示:
这里做的比较有意思的东西是右侧的小标题导航栏,模仿的是终端下输入-tree会显示的文件结构树
不觉得这里的ASCII树状图生成很酷吗
之前在WordPress写文章,用的是功能强大的古腾堡编辑器

呃,是古腾堡,不是符腾堡
这个梗插在这是自娱自乐 ——笔者注
古腾堡编辑器可以把文章也像组件一样解耦,它的原则是万物皆区块,根据区块处理不同的内容,不过这一切真的值得吗?
熟悉古腾堡编辑器的使用可能需要很长时间,我之前做一个点击显示内容的折叠区块,花了半个小时才理解操作步骤,而且最终结果也不尽人意,主要是不好看
但是熟练掌握markdown语法可能只需要半小时,如果马克荡不能满足需求,我们还有超文本标记性语言HTML
文章页面的各种渲染,包括折叠区块,无序号排列,MacOS风格代码块,这些内容的样式都是可以自己调整的,一切权利归博客作者所有
写结构树的时候也遇到了一些棘手的问题,代码已经完善了,但是页面上就是没有显示,后来AI读了VitePress的源码,把默认关闭的标题提取插件打开了修复了这个问题
提这件事主要是因为,如果有前端开发经验或者工程直觉,可能就会大概猜到是出现了什么问题,我当时只能像个傻子一样反复输入“可是我就是看不到,你再改一改”,虽然最终是好结局,但是我觉得解决问题的经验积累十分重要
计划和展望
现在还有一些问题,比如说,没做夜间模式
实际上之前做了夜间模式,但是遇到了一些问题,导致观感不是很好,就暂时性删除了

夜间模式很受到开发者欢迎,一个原因是护眼,一个原因是很装逼
还有导航栏里面的标签页面目前还没做好,如果点击了就会发现什么都没有
现在所有的文章是从上到下按照时间排序的,我觉得应该提供标签检索的功能,还有一些想法是准备跳出Sakura主题的框架,做一些有意思的交互式网页程序
VitePress从来就不只是一个把markdown转换为HTML的工具,它自身就是一个Vue3单页应用,编写的一些网页小程序,可以直接使用Vue的全部生态
除此之外,静态站也是可以实现评论功能,和记录访问次数的,但是目前我还没做
我让AI进行了文章主题和内容的解耦,然后把主题插件上传到GitHub上了,之后如果我自己有什么不满意的地方会继续修改,遇到bug了尽力及时维护,这个项目目前还不算完善,之后会一点一点处理细节
GitHub地址 https://github.com/HoshiiMei/vitepress-theme-hoshii
至于npm上传,等我把这个项目完善得像样了再说吧
一些有趣的事实
- WordPress用于个人博客搭建有点大炮打蚊子,实际上它的服务对象包括商业公司网站、电商平台、社区主页,WordPress支撑起了当前互联网41.9%的网站架构,是目前最受欢迎的内容管理系统(CMS)
- WordPress诞生于2003年,最初只是一个为了方便人们写博客的简单程序。但经过二十多年的演进,凭借其强大的扩展性,它已经发展成一个全能型的建站平台,WordPress的强大在于对各种插件的支持,实现各种网页功能就像是下载应用一样简单
- CMS的设计初衷,就是打破知识壁垒,让不懂代码的人也能创建和设计自己的网页,时至今日,AI已经把这层壁垒碾平了,这篇文章的绝大部分工作是由AI完成的,写的又快又好
- 之前的博客文章保存在_drafts下,但是感觉写的有点太幼稚,就不放出来了,很喜欢xx的一句话,当域名解析时就把昨天忘掉
- 本博客的网页图标取材自韩国二次元手游《碧蓝档案》
- 很多个人博客的实际存活时长不超过半年,可能最开始做的时候很有趣但是后面就没有写东西的动力了,或者是因为太忙放弃做这种费时费力的事情了。顺带一提,这篇文章的绝大部分内容是手写的,AI提供的帮助是弥补专业知识叙述的疏漏。博客重构后,笔者对此发表的宣言是:
