前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Next.js 越来越难用了

Next.js 越来越难用了

作者头像
深度学习与Python
发布2024-06-27 18:09:10
660
发布2024-06-27 18:09:10
举报
作者 | PropelAuth

译者 | Sambodhi

策划 | Tina

导读:在选择下一个项目的框架时,深入了解各选项的优缺点至关重要。尽管 Next.js 强烈推荐使用 App Router(应用路由器),但我们也必须认识到,它仍然存在着诸多不足和复杂性,这可能使其并不适用于所有项目。相比之下,React 官方文档仍持续推荐 Pages Router(页面路由器),并将 App Router 视为前沿技术。本文将深入剖析这两者的差异,并为不同用例下如何选择合适的工具提供建议,助你在复杂性与功能性之间找到完美的平衡点。

最近,我撰写了一篇博客文章,深入探讨了 Next.js 的中间件在应对服务器组件的某些限制方面的作用。这引起了广泛讨论,大家纷纷探讨这种方法是否切实可行,以及 Next.js 的开发体验是否真的不尽如人意。

在我看来,Next.js 的 App Router 存在两大主要问题,导致其难以被广泛应用:

  • 你需要深入了解其内部机制,才能完成看似简单的任务。
  • 其中存在诸多潜在的陷阱,而且这些陷阱默认存在,并非需要用户主动选择才会遇到。

为了更好地理解这些问题,我们可以回顾一下它的前身——Pages Router。

为什么选择 Next.js

而不是 Create React App

当我首次接触 Next.js 时,它当时的“竞争对手”是 Create React App(简称 CRA)。当时我所有的项目都是基于 CRA 来开发的,但之后我选择转向 Next.js,主要有两大原因:

  • 我偏爱基于文件的路由方式,因为它让我能够减少样板代码的编写。
  • 每次启动开发服务器时,CRA 都会自动打开 http://localhost:3000 页面(这种做法很快就让我感到不便),而 Next.js 则没有这样的“贴心”设计。

第二个原因或许显得有些滑稽默,但对我而言,它确实表明了 Next.js:提供了更优秀的 React 默认设置

这正是我所追求的。直到后来,我才发现 Next.js 还有更多功能。API 路由非常吸引我,因为它们无需额外的基础设施配置就能提供无服务器函数,这对于像营销网站的“联系我们”表单这样的功能来说非常便利。getServerSideProps允许我在页面加载前在服务器端运行基础函数。

这些概念不仅功能强大,而且操作起来也十分简单。

API 路由与其他路由处理程序在外观和运作方式上都很相似。如果你曾使用过 Express 或 Cloudflare Workers,那么你只需浏览一下路由处理程序,就能发现其中许多概念都是相通的。至于 getServerSideProps,尽管它有些特别,但一旦你掌握了获取 request 和响应格式的方法,就会发现它也相当容易上手。

Next.js 13 的新功能:

App Router 发布

Next.js 13 版本发布了 App Router,带来了众多新功能。其中,Server Components 的引入使得 React 组件可以在服务器端进行渲染,从而减少了需要发送给客户端的数据量。

此外,新版本还引入了 Layouts 功能,允许开发者定义多个路由共享的 UI 元素,并在每次导航时无需重新渲染,从而提高了页面加载效率。

然而,在缓存方面,新版本却变得更加……复杂。

尽管这些新功能十分有趣,但最大的损失在于简单性的减少。

当框架未按预期工作时

作为开发者,我们都曾有过这样的经历:面对代码难题时,往往会感到困惑并大声问道:“为什么这不起作用?”

这种体验每个人都曾有过,而且总是让人沮丧。对我来说,如果问题并非源于代码本身的 bug,而是源于对事物工作原理的误解,那就会更加令人头疼。

此时,你不再只是疑惑:“为什么这不起作用?”而是开始思考:“为什么它这样工作……而不是那样?”

不幸的是,App Router 就充满了这样的微妙之处。

让我们回到我的最初问题:我仅仅希望在服务器组件中获取 URL。关于这个主题,GitHub 上有一个非常热门的问题的解答,我将在这里分享部分内容:

当我们深入思考时,问题“为什么我无法访问 pathname 或当前 URL?”其实只是冰山一角,其背后隐藏着更大的疑问:“为什么我无法直接访问完整的请求和响应对象?” Next.js 作为一个既能静态也能动态渲染的框架,它巧妙地将工作划分为多个路由段。尽管直接暴露请求 / 响应对象能带来极大的灵活性,但这些对象本质上具有 动态性,它们会影响整个路由的处理。这种设计限制了框架在当前(如缓存和流式传输)以及未来(如部分预渲染)优化方面的能力。 为了解决这一问题,我们曾考虑过直接暴露请求对象并追踪其访问位置(比如使用代理)。但这样的做法会使我们难以追踪这些方法在代码库中的使用方式,并可能导致开发者在不经意间选择了动态渲染。 因此,我们采取了另一种策略,即暴露 Web 请求 API 中的特定方法,并针对不同的使用场景进行了统一和优化:这些 API 覆盖了组件、服务器操作、路由处理程序和中间件等场景。通过这些 API,开发者可以明确选择框架的启发式方法,如动态渲染,同时也让 Next.js 更容易追踪使用情况,分解工作并尽可能优化性能。 举例来说,当使用 headers 时,框架会选择动态渲染来处理请求。而在处理 cookies 时,你可以在 React 渲染上下文中读取 cookies,但只能在变更上下文中(如服务器操作和路由处理程序)设置 cookies,因为一旦开始流式传输,就无法再设置 cookies 了。

这个回答确实非常出色。它不仅写得清晰易懂,而且帮助我对一些底层问题有了更深入的理解,更让我认识到了不同方法之间的权衡,这些我之前完全没有思考过。

然而,话虽如此,如果你是一名开发人员,只是希望在服务器组件中获取 URL,那么在阅读完这篇回答后,你可能还需要进一步查询五个相关问题,最后才会意识到可能需要重新构建或调整你的代码结构。

这篇文章很好地总结了我对此的感受:

这并不意味着它一定是错误的——而是有些出乎意料。

那篇原始文章还提到了一些其他微妙的细节。其中一个常见问题涉及处理 cookies 的方式。你可以在任何地方调用cookies().set("key", "value"),尽管这能通过类型检查,但在某些情况下,运行时可能会出错。

与“旧”方法相比,那时我们可以轻松获取一个完整的request对象,并在服务器上随心所欲地操作,现在的复杂性确实有所增加。

我还要指出的是,“默认开启”的激进缓存策略带来了糟糕的体验。我认为,大多数人更希望自主选择是否使用缓存,而不是在大量文档中苦苦寻找如何关闭它。

在 PropelAuth,我们经常收到的错误报告并非真正的错误,而是用户误以为自己发起了一个 API 调用,但实际上只是读取了缓存的结果。

所有这些都引出了一个问题:这些特性和优化究竟是为了谁而设计的呢?

设计全能产品十分挑战

我所描述的这些过于复杂的特性对一些人来说确实具有重要意义。比如,如果你正在构建一个电子商务平台,这里提供的某些功能就十分出色。

这些功能可以显著提升页面加载速度。因为发送给客户端的数据量减少了,页面加载速度得以加快;由于积极的缓存策略,页面加载速度也得以提升;并且,当用户导航到新页面时,只有页面的部分内容需要重新渲染,这也进一步加快了加载速度。在电子商务领域,页面加载速度的提升意味着更多的收入,因此,为了获得这些优势,你完全会接受使用更为复杂的框架。

然而,如果我是在为我的 SaaS 应用程序构建仪表板,我可能就不会太关心这些功能了。我更注重的是新功能发布的速度,而所有这些复杂性对我的开发团队来说反而成了负担。

我个人对 App Router 的体验和挫折与其他人有所不同,因为我们拥有不同的产品、不同的用例和不同的资源。尤其作为一个长时间投入于编写并帮助他人编写 B2B SaaS 应用程序的人,我认为使用 App Router 的开发体验远不如 Pages Router。

随着框架的发展,

这是不可避免的吗?

随着产品 / 框架的不断发展,它们往往会变得更为复杂。客户的需求会不断增加,大客户更是会提出更为具体的要求。由于大客户支付更多的费用,因此你会优先考虑并构建这些更为具体的功能。

然而,那些曾经喜欢一切简单的客户可能会对不断增加的复杂性感到困扰,然后……瞧,一个全新的框架诞生了,它看起来简单多了。这时,人们会开始呼吁:我们都应该转移到那个新框架上去!

要避免这种局面并不容易,但缓解的一个有效方法是,不要强求所有人都去应对只有部分人需要的复杂性。

推荐的东西并不一定适合你

App Router 面临的一个主要问题是:

Next.js 在 App Router 尚未真正准备好投入生产使用之前就正式推荐了它。Next.js 并未就 TypeScript、ESLint 或 Tailwind 是否适合你的项目给出明确建议(尽管在 TypeScript 和 ESLint 上默认选择了“是”,Tailwind 则选择了“否”—— 抱歉,Tailwind 的粉丝们),但 Next.js 坚定地认为你应该使用 App Router。

然而,React 官方文档却持有不同观点。它们目前推荐的是 Pages Router,并将 App Router 描述为“前沿的 React 框架”。

从这个角度来看待 App Router 会更有意义。与其将其视为 React 的推荐默认选项,不如将其视为一个 beta 版本。它的体验相对复杂,一些原本简单的事情现在变得困难 / 不可能,但这正是“前沿”技术所预期的情况。

因此,当你为下一个项目选择框架时,请注意 App Router 仍存在许多不足。你可能会更容易找到一个更适合你用例的不同工具。

作者简介:

PropelAuth 提供端到端的 B2B 产品管理身份验证服务。

原文链接:

https://medium.com/@PropelAuth/its-not-just-you-next-js-is-getting-harder-to-use-5ab30a24282a

声明:本文为 InfoQ 翻译整理,未经许可禁止转载。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 InfoQ 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档