backgraound-image

我确实不应该用 Nextjs

我个人是比较喜欢追最新最流行的技术栈的,但目前的情形却给了我当头一棒。毫无疑问,Nextjs 是全栈领域的宠,next - npm 显示周下载量将近 600 万,而与其对标的 nuxt - npm 周下载量仅不到 50 万。背靠 react 强大的生态➕Vercel 各种全自动部署方案,显然选择 Nextjs 是一个不错的选择。但用过之后我在打退堂鼓了,并且对追新最流行的行为产生了怀疑。

Nextjs 不能忍受的缺点

龟速的开发环境

下图是运行仅有三个页面,十几个 API 的项目:

其它编译加等待时间,从 npm run dev 开始到首页完全加载完成,超过一分钟的等待时间。并且由于分块加载策略,每跳转到一个新路由都会重新进行编译前后端。尚且不谈热加载,错误提示的问题,可以说得上是极其糟糕的开发体验了。为了开发体验我还特地花了大量时间来定位是我的问题还是 Nextjs 的问题,并升级到 React19 和 Nextjs15。Turbopack Dev is Now Stable | Next.js 这篇文章似乎是拯救编译加载时间于水火,但显然不是!我上面的截图就是升级过后的效果,在这之前编译时间得翻倍!

我的情况显然不是孤例,You don’t need Next.js 用动图的形式表现了用与不用 Nextjs 带来的效果,极大的降低了开发压力。

摸不着头脑的报错

如果编译时间等于摸鱼时间,那时间越长,确实越能摸鱼。但报错就有点难绷了,这个报错就很灵性:

这使得网上的解决办法是 ignoreBuildErrors: true,完全忽视编译错误。

这有可能是我的配置问题,但它显然完全不尊重我的 eslint 配置,难不成我要搞两套 TypeScript 的语法检查?还有更难绷的,同样是由于 nextjs 是仅加载使用到的模块,当你变更底层模块时,在开发环境其它页面没有用到,就不会报错。但一到生产环境,就 GG。

还有那个 Next-Theme,切换个黑夜模式有那么难吗?

后端开发体验同样拉胯

对比专注于后端领域的 nestjs,有着完整的一套解决方案,限流,任务队列,代码结构化等,这些远远好于用 nextjs。后者并没有提供完整的解决方案,啥都得自己拼,文档也少得可怜。为了提升点开发体验,用了 TRPC 库,但同样成为了我后面难以忍受的缺点之一。如果不用 TRPC 库,那得引入其它的后端状态管理和代码组织机制,很可能是 next-auth 加上大量的函数(目前 TRPC 方式写的代码确实调用轻松且优雅)。

但问题是 TRPC 并不是传统 RESTful API,不能直接暴露给第三方用的,没有 OPENAPI 文档,没有 swagger。尽管社区有库可以生成 RESTful API,但是使用下来总是一些并不让人舒服,每个 API 又新添加了若干兼容代码,指不定在以后扩展功能的时候出新的问题而难以脱坑。

同样的,TRPC 并不是完全的 API 抽象,它 不能处理二进制文件,不能很好的兼容 websocket。在优雅的代码上横架了一柄剑,总会在适合的时候让你抓耳挠腮,然后高呼 GG。

生产环境同样出问题

在 shadcn 的官网,cursor 的官网,它们都是使用 Nextjs 构建的,不幸的是我数次碰到渲染错误的页面。尽管刷新一下就好了,但是很难相信这是现代开发框架能出的问题,我几乎没有碰到过直接返回错误页面的 web 网页了,Nextjs 给我上了一课。

Nextjs 不行,还有谁

显然,Nextjs 那么火是有道理的,但我用着怎么那么窝火呢?这些玩意儿有些火得确实并不是代码质量高,开发体验好,react 和 nextjs 向 vercel 靠拢,vercel 提供完整的部署体验。其提供一套 react 开发方案,图片优化,懒加载,SEO,文件路由等机制确实挺好的(我依然没体会出来,tanstack router 实在太香了),有很多大佬提供开箱即用的模板,白嫖也真的很香。这就不提 react 社区和 vercel 之间乌烟瘴气的争论了,Nextjs 的开发体验糟糕不是没有原因的。

选择 Nextjs 真是找罪受,为此我目前的解决方案是:

至于 Remix(听说是真正意义上的 React 全栈框架,和 Nextjs 这种迎合 Vercel 的不一样)和 Nuxtjs 没怎么深入用过,我还是更倾向于像 Astro 这样多框架兼容的框架。