OpenNext 并未使用 Next.js 默认提供的路由系统,而是采用了自身的路由方案。
历史上,OpenNext 曾与 Next.js 使用相同的路由系统。但在 Next 13.4.13 版本中,Next.js 将路由系统移出了 NextServer
,并将应用的主要部分(如 app router、page router 和路由)分离到 jest workers 中。这导致了严重的冷启动问题(默认 create next-app
应用约需 8 秒),且无法在 lambda 中提供 ISR/SSG 页面。自此之后,OpenNext 为所有使用 Next 13.4.13 或更高版本的应用实现了自己的路由系统。值得一提的是,Vercel 在其基础设施中使用了 NextServer
内部未公开的 minimalMode
来绕过路由和缓存系统,而非在 lambda 中处理。
这一改变也使 OpenNext 能够拥有更灵活的路由系统。通过 OpenNext,您可以将路由层置于服务器前的函数中(如 lambda@edge 或 Cloudflare Workers)。您甚至可以直接从路由层提供 ISR/SSG 页面。
以下是 OpenNext 路由系统处理的功能列表:
- 来自
next.config.js
的配置(其余部分由NextServer
自身处理):- Headers(头部信息)
- Redirects(重定向)
- Rewrites(重写规则)
- basePath(基础路径)
- i18n(国际化)
- 中间件
- 可选缓存拦截(即直接从路由层提供 ISR/SSG 内容)
- 在某些情况下处理 404 错误(例如当页面不匹配任何正则路由时)
Next 中间件
OpenNext 中的 Next 中间件运行方式与 Next.js 不同。在 Next.js 中,中间件运行在 NextServer
内部的模拟边缘运行时中。而在 OpenNext 中,我们修改了中间件使其完全在路由层中运行。因此,如果你在 Node 环境中运行路由层,就可以在中间件中使用 Node API(这有些技巧性,因为它无法与 next dev
一起工作,并且需要一些变通方法,因为 Next 会在打包时移除 Node API。可以参考这里的示例)。
在最新的 Next 15 版本(也与最新版 OpenNext 兼容)中,你现在可以在 next.config.ts
中添加一个 experimental
设置来启用 nodejs
作为中间件的运行时:
const nextConfig: NextConfig = {
experimental: {
nodeMiddleware: true,
},
};
// 然后在你的 `middleware.ts` 中添加:
export const config = {
runtime: "nodejs",
};
这是 Next.js 中引入该功能的 PR (opens in a new tab)。