这个博客多年来经历了很多变化。多年来一直是 WordPress,后来是 Jekyll、OctoPress、Middleman,以及最近使用 WordPress 的 Next.js。
2024 年,我不再喜欢 Next.js。多年来我一直是它的大力支持者。 Hardcover是建立在它的基础上的(尽管我们正在迁移到 Ruby on Rails + Inertia.js),我什至创建了 Nextjsbits.com,一个关于 Next.js 的博客。我写了很多关于 Next.js 的博客文章,并发布在 Next.js Reddit 子版块上。换句话说,我觉得这非常棒。
我们几乎一选择就切换到 Next.js App 目录。我对使用 React Server Components 感到非常兴奋,以至于我放弃了所有测试警告并全速前进。它成功了!至少在功能上是这样。
慢慢地,问题开始潜入。我们的构建时间激增,有时在本地花费一分钟的时间来完成一条本应只需要几分之一秒的路线。由于从客户端数据加载转向服务器端加载,我们的 Vercel 账单从每月 20 美元增加到 500 美元。我(错误地)以为我了解缓存的工作原理,后来才意识到几乎没有任何内容被缓存 – 但即便如此,我也没有深入了解实际缓存的内容。
有问题。开发体验较慢。生产体验较慢。调试起来比较慢。
从那以后我花了很多时间试图理解出了什么问题。在最新版本的 Next.js 中,使用 Turbo 进行本地开发可能是可能的 – 但到发布时,Hardcover 的迁移已接近终点线。
到 2024 年 10 月,我感到沮丧,开始寻找其他选择。一旦精装版重写完成,我将分享有关该过程的更多信息。
2024 年 11 月,大选结束后,Vercel 首席执行官 Guillermo Rauch 在 X 上发帖表达了他对特朗普的支持。大约在同一时间,Sticker Mule 的首席执行官也发表了类似的声明。
你的关注和你的花费就是选票。虽然我知道 Next.js 是一个拥有许多出色开发人员的项目,但 Vercel 是一家企业,也是 Next.js 背后的支持力量。
我决定开始从我的项目中删除 Next.js。我关闭了 Next.js Bits。我将 Hardcover 从 Vercel 迁移到 Google Cloud Run。精装本正在被迁移。最后,这个博客现在在Astro上运行!
从 Next.js 迁移到 Astro
在看到 Astro 在年度 JavaScript 调查中获得高满意度后,它吸引了我。当我意识到他们的官方文档中有一个关于Headless WordPress 和 Astro 的部分时,我知道这是一个完美的选择。
Next.js 和 Astro(或我的具体实现)之间的最大区别在于页面的渲染方式。使用 Next.js,页面都会在第一次请求时呈现。对于此博客,每个页面在构建时都会呈现为静态 HTML。这意味着它超级快!
这也有缺点。当我撰写或编辑新帖子时,只有触发整个网站的重建后,该帖子才会立即可用。这也意味着评论(使用 WordPress)不是一个选项。这是我还需要弄清楚的事情。
当我开始搜索“astro WordPress headless cms”时,出现了大量视频!这也让我找到了这个很棒的 Astro 入门模板。
我决定从头开始使用npm create astro@latest
并从那里开始。
将 Next.js 页面转换为 Astro
我的第一步是列出所需的路线。还有一些路线我还没有移动过(例如:读过的书、发的照片)。
-
/
– 有趣的登陆页面。 -
/projects
– 我曾经参与过的所有项目,由 WordPress 提供支持。 -
/blog
– 我所有项目博客中的所有博客文章的列表。 -
/blog/projects
– 所有项目的列表。 -
/blog/projects/:project/:page
– 按项目分页的帖子列表 /blog/all/:page
– 分页的帖子列表。-
/blog/tags
– 所有标签的列表。 -
/blog/tags/:tag/:page
– 按标签分页的帖子列表。 -
/newsletter
– 订阅我的新闻通讯的表格(提交给 Sendy)。 -
/newsletter/thanks
– 注册后重定向。 -
/:post
– 与 WordPress URI 对应的单个帖子或页面。
就是这样!不是太多。我从周二开始转换一切,到周六,一切都正常了!
迁移中最困难的部分是将 React.js 组件移至 Astro 组件。幸运的是,只有少数地方需要客户端代码(即主页和项目页面)。
其中大多数都相对简单,例如Article组件。其他更高级的组件我保留为 React(暂时),例如项目列表组件。获取数据发生在 Astro 中,然后将项目传递给 React 进行交互。
从 WordPress 获取数据
幸运的是, WordPress 方面没有任何变化。我移走了之前所有的fetch GraphQL 客户端、 TypeScript 类型和所有GraphQL 查询。
我决定在这个博客上列出来自adamfortuna.com
、 hardcover.app和minafi.com 的帖子——我在这三个博客上花了很多时间。但是,只能看到来自 adamfortuna.com 的个别帖子。
这意味着当涉及到列出帖子或按标签列出帖子时,我需要从所有三个博客中获取帖子并按日期对它们进行排序。
解决方案是访问所有三个博客,解析结果并对它们进行排序。 这个代码有点繁琐,但是可以完成工作。这些函数中的大多数都接受要从中获取的项目数组,这样如果我想稍后添加另一个博客,我可以轻松添加它。
WordPress 可以允许无需身份验证的 GraphQL 访问,但某些字段将不可用。最重要的是作为常规文本excerpt
。我在元描述中使用它,并将其显示在突出显示的帖子的博客列表页面上。这意味着需要进行身份验证。
我为每个博客创建了代表用户名和密码的令牌,然后将其设置为环境变量。
天文分页
迁移过程中我最喜欢的部分是使用 Astro 的分页。每个分页页面都非常简单。 getStaticPaths
方法提供了一个paginate
函数,可用于从同一数据数组创建多个分页页面。您甚至不需要对数组进行切片!
嵌套路由的分页需要更多的工作。例如, /blog/projects/:project/:page
。 此页面需要使用项目数组并获取每个项目的所有帖子,然后对它们进行分页。 标签页上也使用了相同的技术。
Astro 解决方法
为了与 Astro 和静态生成良好配合,我需要更改两个部分。
第一个是在标签页面的帖子上。当 Astro 尝试加载路线/blog/tags/:tag/:page
时,它必须做很多工作。它加载所有标签,然后访问所有三个博客以获取每个博客的所有标签。到目前为止,有 70 个标签,这意味着超过 200 个请求。这不会是一个问题,但使用Promise.all
这样做意味着一次会对 WordPress 进行 70 个请求的 DDOS。
我改以串行方式而不是并行方式进行这些操作,这似乎成功了。
下一个问题是,由于所有这些 API 调用,开发速度很慢。这件事很简单。我将这些保存的值缓存到本地变量中并使用它们。如果 Astro 有更好的方法来做到这一点,请指出我的方向。
最后一个主要问题是将 Tailwind.css 从版本 3 更新到版本 4。当我意识到 CSS 文件中的@config ‘../../tailwind.config.js’选项后,整个过程就顺利进行了。以前,我使用@screen md {}
选项将限制更改为@media(min-width: theme(--breakpoint-md)) { }
。
托管
几个月前,我从 Vercel 切换到Netlify ,并且一直很喜欢它。我还没有尝试过任何大事,但对于我的博客来说,它非常棒。
我在那里设置了 Astro,并且它在第一个版本中工作了!
下一步是什么
到目前为止,这是一个有趣的项目。接下来还有几件事我还想做。
- 当 WordPress 发生变化时触发重建
- 弄清楚如何处理评论和网络提及
- 添加一个书页,显示我已读过或正在阅读的内容
- 添加一个电影页面,显示我看过的内容。
- 电视节目也一样。
- 添加徒步旅行列表,也许使用类似这样的东西。
- 添加回我的照片帖子。我已经用 WordPress 写了一些。
- 添加深色模式
- 让主页变得更有趣!