选框架就花了两周。真正写代码反而快,三天搞完——然后 View Transitions 的 bug 调了四天。
对了,如果你也想自己搭博客,我写了个零成本建站教程,跟着做就行。
选框架
选框架这件事折腾了挺久。跟当初选游戏引擎一样纠结。
最开始试的 Hexo,毕竟教程最多。但一打开就有种回到2015年的感觉,很多插件最后更新还是三四年前。总觉得不太对,pass。
然后看了 Hugo,人人都说它快。确实快,但我一看模板语法—— {{ .Params.title }} ——作为一个没编程基础的人,我盯着屏幕看了五分钟完全不知道自己在看什么。pass。
也看了 Next.js。React 全家桶,功能确实强。但我就想写写 Markdown 生成静态页面,它给我整了 SSR、API Routes、状态管理……大哥我搭个博客又不是做 SaaS。pass。
最后刷到了 Astro。默认输出纯静态 HTML,零 JavaScript;支持 Markdown;组件语法跟 HTML 差不多;还内置了 View Transitions 页面过渡动画;文档也写得清楚。
试了一下午就决定用这个了。后面从零到部署上线,整个过程确实比预想的顺——当然,除了 View Transitions 这个大坑。
Cloudflare Pages
部署选了 Cloudflare Pages。
选Cloudflare Pages纯粹因为——免费。GitHub推一下代码就自动部署,不用碰服务器。唯一踩到的坑是单文件25MB限制,几个BGM文件超了,ffmpeg压了一轮才传上去。
域名是 huannan.top,DNS 也托管在 Cloudflare。一站式搞定,不用到处折腾。
View Transitions 的坑

Astro 6 内置了 View Transitions(页面过渡动画),用起来很简单——加一行 <ClientRouter /> 就行。
但这玩意儿是个大坑。
它干的事情大概是:点击链接时不刷新整个页面,而是用 AJAX 请求新页面的 HTML,然后”软替换”当前页面的内容。听起来挺好的对吧?
问题是——你的 JavaScript 脚本不会重新执行。
我的音乐播放器、主题切换、图片灯箱,全部是用 <script is:inline> 写的。第一次加载页面的时候一切正常,但是点击导航到另一个页面,这些脚本就不跑了。因为 Astro 检测到新旧页面的脚本内容一样,就跳过了。
结果就是:导航到新页面后,主题切换按钮点了没反应,图片点了不放大,音乐播放器消失了。
修了好久。最后是这么搞的:
- 音乐播放器加
transition:persist,让它跨页面存活 - 主题切换用
astro:after-swap事件恢复暗色模式 - 其他脚本用
astro:page-load事件重新绑定
这些 Astro 文档里都有提到,但就写了一两句。根本看不出来会出这么多问题。
Tailwind CSS
样式用的 Tailwind CSS v3。
一开始觉得在 HTML 里写一大堆 class="flex items-center gap-3 px-4 py-2 bg-white rounded-xl shadow-sm" 很丑很乱。但用了一段时间之后发现——真香。
不用想 class 名字,不用在 CSS 文件里来回切换,改样式就在标签上改,改完就能看到效果。反正我也不太会写 CSS,Tailwind 这种直接往标签上堆的方式反而更容易上手。
暗色模式也很方便。加个 dark: 前缀就行:text-gray-800 dark:text-gray-200。
不过有一个坑:Tailwind 的 JIT 模式下,动态拼接的 class 名不会被识别。比如 `stagger-${i}` 这种写法,Tailwind 不知道你用了 stagger-1 到 stagger-6,就不会生成对应的 CSS。解决办法是在 global.css 里手动写好这些 class。
开发模式
整个网站的代码生成主要靠 Claude Code,我负责需求设计和代码审阅。
自己从头手写每一行代码太慢了,用 AI 生成效率高很多。但也别想着什么都丢给它——审阅的工作量一点都不小。
AI 写的代码有时候会有一些微妙的 bug,你不仔细看发现不了。比如它把 bottom: 24px 写成内联样式,然后在 JS 里又用 Tailwind 的 class 去覆盖,两边打架导致播放器位置不对。
这种问题就得自己盯着。代码可以让 AI 写,但出了问题还是得自己兜底。
下一篇聊音乐播放器。那个东西是整个网站最复杂的部分。
你可能还想看