博客翻新记
22 年用 hexo 搭的博客,24 年 3 月迁到 vitepress——那时候 vitepress 刚出 1.0 正式版,第三方主题生态基本是空白,只能套默认主题凑合,看起来就是个文档站。当时想的是以后有人做皮肤了再换,结果一凑合就是两年多。今天难得有空,给博客来了次大翻新,顺便把攒了两年的账都清了。
干了什么
一句话总结:换了主题、换了评论系统、导了一批旧文章、升级了依赖、重写了 git 历史。
主题换成了 Teek。现在的 vitepress 主题生态已经很成熟了,比较了一圈(Teek、@sugarat/theme、blog-pure 这些),最后选了 Teek:中文文档最全、2026 年还在活跃更新、基于默认主题扩展所以老配置基本都能直接用。换完首页有了正经博客的样子——文章列表带分页、分类卡片、标签卡片、站点统计(多少篇、多少字、访问量),不再是光秃秃的 hero 页。
评论从 gitalk 迁到 giscus。gitalk 这东西有个先天缺陷:OAuth clientSecret 必须明文放在前端配置里,等于密钥公开挂着,而且它依赖的 axios、react 全是老版本,npm audit 一片红,GitHub 天天给我发漏洞邮件。giscus 基于 GitHub Discussions,不需要任何密钥,评论区数据也存在 Discussions 里,干净多了。
导入了 27 篇旧文章。之前攒在飞书文档里的技术笔记,这次全部导了出来。导之前逐篇做了脱敏——内网地址换成占位符、公司名和内部项目代号全部替换、内部截图(发出来也是死链)直接移除。中间还有些纯内部资料(周报、交接文档、保密自查表之类的)直接没导。最后上线 27 篇,按 AI 与编程工具 / 前端技术 / 项目实践分了类。
依赖全升。vitepress 从 1.0.1 升到 1.6.4,vue 到 3.5.42,gitalk 和 busuanzi 直接移除(统计换成 Teek 内置的)。漏洞从 14 个降到 7 个,剩下的全是 vite 5 自带 esbuild 的开发服务器提示,不影响线上。
git 历史重写。有篇文章不想留了,光删文件没用,得从历史里彻底清掉。用 git filter-branch --tree-filter --prune-empty 重写了整个 master,再配合强推。仓库小(56 个提交),四十秒就跑完了。
踩的坑
这部分才是本文的价值所在,给同样想迁移的人避雷。
坑一:Teek 不能在 config.mts 里从包根导入
最坑的一个。按照文档在 config.mts 里写:
import { defineTeekConfig } from 'vitepress-theme-teek' // ❌ 构建必挂构建直接报 Cannot find module '...theme-default/without-fonts'。原因是 config.mts 的加载走 Node 原生 ESM,包根入口会连带 import vitepress/theme,而 vitepress 的主题入口里有无扩展名的相对导入和 CSS 导入,这两种东西 Node 原生 ESM 都解析不了。vite 开发服务器没事,因为它有自己的模块解析器,所以 dev 能跑、build 必挂,非常有迷惑性。
正确写法是从深层入口导入:
import { defineTeekConfig } from 'vitepress-theme-teek/config' // ✅这个入口只有配置函数和 vite 插件注册,链路上不碰 vitepress/theme。
坑二:主题样式要手动引入
theme/index.ts 里光 import Teek from 'vitepress-theme-teek' 不够,所有图标会变成巨大的图形占满屏幕。要显式引入样式:
import Teek from 'vitepress-theme-teek'
import 'vitepress-theme-teek/index.css' // 不加这个图标会爆炸坑三:Teek 的自动侧边栏会盖掉自定义配置
我明明在 themeConfig 里写了分组 sidebar,页面上却显示一个按文件名字母排序的平铺列表。查了半天发现 Teek 的 vitepress-plugin-sidebar-resolve 插件默认开启,会按文件树自动生成侧边栏,优先级高于手写配置。关掉就好:
defineTeekConfig({
vitePlugins: { sidebar: false },
// ...
})坑四:Markdown 链接里的空格
索引页一堆链接 404,查下来是 CommonMark 的规范:链接目标带空格必须用尖括号包裹,否则链接在第一个空格处截断。
[标题](/blog/Hello world) // ❌ 解析成指向 /blog/Hello 的链接
[标题](</blog/Hello world>) // ✅文件名带空格的文章全中招,肉眼还不容易看出来——渲染出来链接文字是对的,只是点不动。
坑五:Windows 下构建和预览打架
vitepress preview 跑着的时候重新 build,Windows 会报 EBUSY: rmdir dist——预览进程占着目录。而且偶尔还有杀毒软件来凑热闹,锁几分钟不放。经验:build 前先停预览;实在不行 build 到别的目录(npx vitepress build Blog --outDir dist_new),反正 CI 部署时是全新构建,本地 dist 不影响上线。
坑六:git 历史重写的正确姿势
- 重写前先打备份分支:
git branch backup-pre-purge git filter-branch --tree-filter '删除脚本' --prune-empty master,--prune-empty会把清空后的空提交一并剪掉- 重写后用
git grep 目标字符串 $(git rev-list master)验证全历史无残留 - 推送用
--force-with-lease而不是--force,至少保证不会覆盖掉别人(或者自己另一台机器)的新提交 - 本地的备份分支确认没问题后删掉,不然旧历史一直躺在本地
一点感受
默认主题用了两年,一直觉得"够用了"。真换过来才发现博客该有的东西——归档、分类、标签、像样的评论——早就该有了。技术选型这事,等生态和等自己动手之间,还是后者靠谱。
另外这次深刻体会到:公开仓库里翻新历史要趁早。明文密钥挂了两年多才处理,虽然大概率没人看这个小博客,但真被人扫到就是麻烦。各位如果有类似情况的,赶紧去 Settings → Developer settings 里把不用的 OAuth App 删了。