我确实不应该用 Nextjs
我个人是比较喜欢追最新最流行的技术栈的,但目前的情形却给了我当头一棒。毫无疑问,Nextjs 是全栈领域的宠,next - npm 显示周下载量将近 600 万,而与其对标的 nuxt - npm 周下载量仅不到 50 万。背靠 react 强大的生态➕Vercel 各种全自动部署方案,显然选择 Nextjs 是一个不错的选择。但用过之后我在打退堂鼓了,并且对追新最流行的行为产生了怀疑。
Nextjs 不能忍受的缺点
龟速的开发环境
下图是运行仅有三个页面,十几个 API 的项目:
- 启动花了 21s
- 编译首页花了 17.6s
- 编译 api 花了 8.7s
其它编译加等待时间,从 npm run dev
开始到首页完全加载完成,超过一分钟的等待时间。并且由于分块加载策略,每跳转到一个新路由都会重新进行编译前后端。尚且不谈热加载,错误提示的问题,可以说得上是极其糟糕的开发体验了。为了开发体验我还特地花了大量时间来定位是我的问题还是 Nextjs 的问题,并升级到 React19 和 Nextjs15。Turbopack Dev is Now Stable | Next.js 这篇文章似乎是拯救编译加载时间于水火,但显然不是!我上面的截图就是升级过后的效果,在这之前编译时间得翻倍!
我的情况显然不是孤例,You don't need Next.js 用动图的形式表现了用与不用 Nextjs 带来的效果,极大的降低了开发压力。
摸不着头脑的报错
如果编译时间等于摸鱼时间,那时间越长,确实越能摸鱼。但报错就有点难绷了,这个报错就很灵性:
- 开发的时候不报错
- 编译到生产环境时就报错
- 它只显示最近的一个错误,你改了一个,你得重新运行
npm run build
编译才会提示下一个错误 - 你试图用
next lint
找出全部语法错误,不好意思,没错误,通过!
这使得网上的解决办法是 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。
真不想用 Nextjs
显然,Nextjs 那么火是有道理的,但我用着怎么那么窝火呢?这些玩意儿有些火得确实并不是代码质量高,开发体验好,react 和 nextjs 向 vercel 靠拢,vercel 提供完整的部署体验。其提供一套 react 开发方案,图片优化,懒加载,SEO,文件路由等机制确实挺好的(我依然没体会出来,tanstack router 实在太香了),有很多大佬提供开箱即用的模板,白嫖也真的很香。
如果不是 react 开发多页面,需要 SEO,选择 Nextjs 真是找罪受。