又重构了,这次用Next.js 16

预计阅读 5 分钟

1. 说好不折腾的

上一篇文章刚写完《为何选择Astro搭建静态博客》,我就开始琢磨能不能再折腾一下。

Astro确实很好,上手快、结构简单、部署稳。但用了一段时间之后,我发现自己越来越想要一些它不太擅长的东西——没法实现更灵活的组件交互、和复杂的动画效果。

于是我就开始想:既然AI辅助编程现在这么强大,要不直接上Next.js?毕竟react和Next.js被AI训练了很多了,也可以实现很多功能了。

上次Next.js是因为安全漏洞的事胎死腹中,但那是Next.js 14的老黄历了。这次Next.js 16出来,顺势就重构了。

2. 技术栈

这次整体选型如下:

  • 主框架是 Next.js 16,用 App Router,文章渲染用 next-mdx-remote
  • 样式用 Tailwind CSS v4,排版用官方的 @tailwindcss/typography 插件
  • 代码高亮用 rehype-highlight,主题是 tokyo-night-dark
  • 图片灯箱用 PhotoSwipe,支持点击放大、滑动切换
  • 评论系统还是 Waline,与Astro一致,加入了 Cloudflare Turnstile 人机验证,希望能挡住垃圾评论
  • 部署在 Vercel,用 Cloudflare 做 DNS 和防护
  • 图床继续用 Cloudflare R2,域名绑的是子域名

跟Astro版本相比,最大的变化是文章从纯 Markdown 升级成了 MDX——可以在文章里直接用自定义组件,比如现在的图片就是一个专门写的 <Image> 组件,支持对齐、宽度、描述文字、灯箱缩放这些参数,写文章的时候灵活很多。但是还是有别的问题,比如说不能实现更加复杂的图文混排,这一点和富文本编辑器没法比,毕竟还是markdown。

3. 折腾过程

这一次主要使用AI辅助编程,好在个人博客的项目不大,也没有什么特别复杂的处理逻辑,现在只能算是个demo,能跑起来就是胜利,希望大模型能更强大了,以后自己可以鼓捣出来更好的形态。

比较花时间的地方是目录组件。目录的高亮逻辑用的是 IntersectionObserver,但光靠它在某些滚动场景下会失灵,最后加了一个基于滚动位置的降级方案才稳定下来。另外 PhotoSwipe 的图片尺寸问题也绕了一圈——它需要提前知道图片的宽高,但图片是异步加载的,最后用 img.complete 判断加载状态,再把尺寸存到 dataset 里解决的。

代码高亮和 MDX 渲染的配合也有一点小坑:rehype-highlight 处理完的代码块是带高亮标签的 HTML 结构,复制代码时不能直接读 innerText,得递归提取纯文本才行。

当然,现在并没有完善所有的细节,还有很多地方不太满意,首先就是前面提到的图片问题,纯Markdown的图片写法,没办法渲染了,只能基于 <Image> 组件。其次就是有的页面的交互还是不太满意,自己还需要继续打磨修改。

4. 现在怎么更新博客

跟之前差不多,还是很简单:

  1. 打开 Typora,在src/posts里新建一个.md文件
  2. 写完保存
  3. 用GitHub Desktop同步到仓库
  4. 等Vercel自动部署,两分钟后刷新——好了

MDX的自定义组件也可以直接在Typora里写,保存就是保存,不需要任何额外操作。

5. 碎碎念

这次重构之前,其实犹豫过要不要继续用Astro的。但想了想,折腾本身也是一种乐趣,而且通过这次重构确实学到了不少React和Next.js的细节。

技术栈没有好坏之分,只有合不合适。Astro很好,Next.js 也很好,就看你想要什么。

希望这次能稳定久一点,别再折腾了……吧。

评论