搜索
首页web前端js教程Next.js v——反思错误

你好!这是另一篇关于 next.js 的文章。最后,关于新版本!每个版本都包含一组新的、有趣的和有争议的功能。这个版本也不例外。然而,新版本的有趣之处并不在于它的新功能,而是在于 next.js 中优先级和组织的变化。是的,正如您可能从标题中猜到的那样,此版本的重要部分对于反思以前的错误很有价值。

从版本 8 左右开始,我就一直在使用 next.js。一直以来,我一直饶有兴趣地关注它的开发(有时并非没有失望)。最近,我发表了一系列关于与新的 App Router 作斗争的文章 - “Next.js App Router。通向未来的道路还是错误的转折”、“Next.js 缓存。礼物还是诅咒”、“为图书馆之神提供更多图书馆或我如何重新思考 i18n”。所有这些都是 next.js 之前版本的思想和功能开发非常薄弱的​​结果。正因为如此,我对新版本的兴趣有增无减。除此之外,人们还渴望了解框架中的变化向量。

在本文中,我不会详细讨论 App Router 或服务器组件是什么 - 这些在之前的文章中有详细描述。我们将只关注新版本和新变化。

注:文章反映了从作者角度来看最有趣的变化。它们与官方列表不同,因为作者是从框架中的提交和 PR 中选择的。

Next.js v15 发布

首先,介绍一下 next.js 内部开发流程的变化。框架团队首次发布了候选版本(RC 版本)。显然,他们这样做是因为 React.js 团队决定发布 React v19 RC。

通常,稳定版本中的 next.js 团队会平静地使用“Canary”版本分支中的 React(该分支被认为是稳定的,建议框架使用)。然而,这一次,他们决定采取不同的做法(剧透 - 没有白费)。

两个团队的计划都很简单 - 发布预发布版本,让社区检查问题,然后在几周内发布完整版本。

Next.js v— Reflecting on Mistakes


来自 React.js 核心团队开发人员的推文 https://x.com/acdlite/status/1797668537349328923

React.js 的候选版本发布已经过去了 6 个多月,但稳定版本仍未发布。 React.js 稳定版本的延迟发布也影响了 next.js 的计划。因此,与传统相反,他们在第 15 个版本已经开始工作的同时,总共发布了 15 个附加补丁版本(通常是 3-5 个补丁,然后发布一个版本)。这里值得注意的是,这些补丁版本并没有包含所有累积的更改,而只是解决了关键问题,这也偏离了 next.js 的通常流程。

next.js 中的基本发布流程是,所有内容都合并到金丝雀分支中,然后在某个时刻,该分支作为稳定版本发布。

然而,因此,next.js 团队决定与 React.js 版本解耦,在 React.js 稳定版本发布之前发布稳定版本的框架。

文档版本控制

另一个非常有用的组织变革。最后,可以查看不同版本的文档。这就是为什么这如此重要:

首先,由于重大变化,更新 next.js 通常是一项相当具有挑战性的任务。事实上,这就是为什么版本 12 的下载量仍然超过 200 万次,版本 13 的下载量每月超过 400 万次(公平地说,版本 14 的下载量超过 2000 万次)。

因此,以前版本的用户需要特定于其版本的文档,因为新版本可能会重写一半。

Next.js v— Reflecting on Mistakes


Next.js 文档版本控制 - nextjs.org/docs

另一个问题是 Next.js 本质上使用单个通道。文档也对其进行了更改。因此,金丝雀版本的更改描述立即出现在主要文档中。现在它们显示在“金丝雀”部分下。

使用反应

一开始,我提到 Next.js 目前正在使用 React.js 的 RC 版本。但事实上,这并不完全正确,或者说不完全正确。事实上,Next.js 目前使用两种 React.js 配置:App Router 的第 19 个金丝雀版本和 Pages Router 的第 18 个版本。

有趣的是,有一次他们也想包含 Pages Router 的第 19 版,但后来又回滚了这些更改。现在,在稳定版本发布后,承诺全面支持 React.js 版本 19。

除此之外,新版本还将对服务器操作功能进行一些有用的改进(是的,React团队将它们重命名为):

  • 重量和性能优化;
  • 改进的错误处理;
  • 修复了服务器功能的重新验证和重定向。

我想我也会在本节中包含 Next.js 的新功能 - Form 组件。总的来说,它是 React-dom 中熟悉的形式,但有一些改进。如果成功提交表单涉及导航到另一个页面,则主要需要此组件。对于下一页,将预加载loading.tsx和layout.tsx抽象。

import Form from 'next/form'

export default function Page() {
  return (
    
; {/* On submission, the input value will be appended to the URL, e.g. /search?query=abc */} ; ;
; ) }

开发者体验 (DX)

在谈论 Next.js 时,我们不能忽视开发者体验。除了“更快、更高、更强”标准(我们稍后也会讨论)之外,还发布了一些有用的改进。

期待已久的对最新 ESLint 的支持。 Next.js 到目前为止还不支持 ESLint v9。尽管 eslint 本身 (v8) 及其一些子依赖项已被标记为已弃用,但情况仍然如此。这导致了一种不愉快的情况,项目基本上被迫保留已弃用的包。

错误界面略有改进(在 Next.js 中已经清晰方便):

  • 添加了复制堆栈跟踪的按钮;
  • 添加了在编辑器中的特定行打开错误源的功能。

Next.js v— Reflecting on Mistakes


在 next.js 中复制错误堆栈的示例

添加了“静态指示器” - 页面一角的一个元素,显示页面已在静态模式下构建。
总的来说,这是一件小事,但有趣的是他们将其作为新的东西包含在关键更改中。 “预建”页面的指示器大约从版本 8 (2019) 开始就已经存在,本质上,他们只是稍微更新了它并针对 App Router 进行了调整。

Next.js v— Reflecting on Mistakes

还添加了包含调试信息的目录 - .next/diagnostics。它将包含有关构建过程和发生的所有错误的信息。目前尚不清楚这在日常使用中是否有用,但在解决 Vercel devrel 问题时肯定会使用它(是的,它们有时有助于解决问题)。

Next.js v— Reflecting on Mistakes
Next.js 团队对 [关于项目构建速度缓慢的推文] 的回应(https://x.com/darshansrc/status/1797339543571755425)

构建过程的变化

讨论完 DX,值得谈谈构建过程。还有 Turbopack。

涡轮机组

以及该领域最大的新闻。 Turbopack 的开发模式现已完全完成! “Turbopack 100% 的现有测试均通过且没有错误”

现在Turbo团队正在开发生产版本,逐步进行测试和完善(目前完成约96%)

Next.js v— Reflecting on Mistakes
next.js 中的示例变更日志部分

Turbopack 还添加了新功能:

  • 使用 Turbopack 设置构建的内存限制;
  • Tree Shaking(删除未使用的代码)。
import Form from 'next/form'

export default function Page() {
  return (
    
; {/* On submission, the input value will be appended to the URL, e.g. /search?query=abc */} ; ;
; ) }

Turbopack 中的这些和其他改进“减少了 25-30% 的内存使用量”,并且“将大量页面的构建速度加快了 30-50%”。

其他

重大的样式问题已得到修复。在版本 14 中,经常会出现导航过程中样式顺序被破坏的情况,导致样式 A 高于样式 B,反之亦然。这改变了它们的优先级,因此元素看起来不同。

下一个期待已久的改进。现在可以用 TypeScript 编写配置文件 - next.config.ts

const nextConfig = {
  experimental: {
    turbo: {
      treeShaking: true,
      memoryLimit: 1024 * 1024 * 512 // in bytes / 512MB
    },
  },
}

另一个有趣的更新是重试静态页面构建。这意味着如果页面在构建时失败(例如,由于互联网问题) - 它将尝试再次构建。

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

总结本节,这是社区非常期望的功能 - 指定用于构建的其他文件的路径的能力。例如,使用此选项,您可以指定文件不位于应用程序目录中,而是位于 module/main、modules/invoices 等目录中。

但是,目前他们仅出于团队内部目的添加它。而在这个版本中,他们肯定不会呈现。展望未来,它将用于满足 Vercel 需求,或者他们将对其进行测试并在下一个版本中呈现。

框架 API 的变化

Next.js 更新中最痛苦的部分 - API 更改。并且在这个版本中,还有重大更新。

几个内部框架 API 已变为异步 - cookies、headers、params 和 searchParams(所谓的动态 API)。

const nextConfig = {
  experimental: {
    staticGenerationRetryCount: 3,
  },
}

这是一个重大变化,但 Next.js 团队承诺所有这些功能都可以通过调用他们的 codemod 自动更新:

npx @next/codemod@canary next-async-request-api .

另一个变化,但可能与很多人无关。密钥 geo 和 ip 已从 NextRequest 中删除(用于中间件和 API 路由)。本质上,此功能仅在 Vercel 中有效,而在其他地方开发人员则制定了自己的方法。对于 Vercel,此功能将移至 @vercel/functions 包

还有一些更新:

  • 在 revalidateTag 中,您现在可以一次传递多个标签;
  • 键 images.remotePatterns.search 和 images.localPatterns 已添加到 next/image 的配置中。这些可以更好地控制图像压缩的地址限制。
import Form from 'next/form'

export default function Page() {
  return (
    
; {/* On submission, the input value will be appended to the URL, e.g. /search?query=abc */} ; ;
; ) }

缓存

在我个人看来,这是 Next.js 最重要的变化发生的地方。最大的消息是 - 现在默认禁用缓存我不会详细讨论缓存问题,这在“Next.js 缓存。礼物还是诅咒”一文中主要介绍了。

让我们看看缓存中的所有主要变化:

  • 具体来说,fetch 现在默认使用 no-store 值而不是强制缓存;
  • API 路由现在默认在强制动态模式下工作(之前默认为强制静态,这意味着它们在构建时被编译为静态响应[如果页面上未使用动态 API]);
  • 客户端路由器中的缓存也已被禁用。以前,如果客户端访问路由中的页面 - 它会被缓存在客户端上并保持该状态,直到重新加载页面。现在,每次都会加载当前页面。可以通过 next.config.js 重新配置此功能:
const nextConfig = {
  experimental: {
    turbo: {
      treeShaking: true,
      memoryLimit: 1024 * 1024 * 512 // in bytes / 512MB
    },
  },
}
  • 此外,即使启用了客户端缓存 - 它显然也会在正确的时刻更新。具体来说,如果服务器上启用的页面的缓存过期。
  • 服务器组件现在在开发模式下缓存。这使得开发更新发生得更快。只需重新加载页面即可清除缓存。您还可以通过 next.config.js 完全禁用此功能:
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;
  • 您现在可以管理“Cache-Control”标头。以前,它总是被 Next.js 的内部值严格覆盖。这导致了通过 CDN 进行缓存的工件;
  • next/dynamic 缓存模块并重用它们,而不是每次都重新加载它们;

这就是关于“历史误会”的问题。新的 API 也将出现在 Next.js 中。即所谓的动态I/O。目前还没有任何相关的文章,所以以下是作者根据改动的猜测。

动态 I/O 似乎是动态构建的高级模式。类似于 PPR(部分预渲染),或者更准确地说,它的补充。简而言之,部分预渲染是一种页面构建模式,其中大多数元素在构建时构建并缓存,而单个元素则针对每个请求构建。

因此,动态 I/O [可能] 最终确定了该逻辑的架构。它扩展了缓存功能,以便可以根据模式和使用地点精确地启用和禁用它(是否在“动态”块中)。

import Form from 'next/form'

export default function Page() {
  return (
    
; {/* On submission, the input value will be appended to the URL, e.g. /search?query=abc */} ; ;
; ) }

除此之外,还添加了“使用缓存”指令。它将在 Nodejs 和边缘运行时中可用,显然,在所有服务器段和抽象中都可用。通过在函数或导出函数的模块顶部指定此指令 - 其结果将被缓存。该指令仅在启用dynamicIO时才可用。

const nextConfig = {
  experimental: {
    turbo: {
      treeShaking: true,
      memoryLimit: 1024 * 1024 * 512 // in bytes / 512MB
    },
  },
}

另外,专门为了使用缓存,添加了方法cacheLife和cacheTag

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

cacheTag将用于使用revalidateTag进行重新验证,cacheLife将设置缓存生存期。对于cacheLife 值,您需要使用预设值之一。几个开箱即用的选项(“秒”,“分钟”,“小时”,“天”,“周”,“最大”),可以在 next.config.js 中指定其他选项:

const nextConfig = {
  experimental: {
    staticGenerationRetryCount: 3,
  },
}

部分预渲染 (PPR)

可能是下一个版本的主要功能。如前所述,PPR 是一种页面构建模式,其中大多数元素在构建时组装并缓存,而单个元素则针对每个请求进行组装。同时,预构建的部分会立即发送到客户端,而其余部分则动态加载。

Next.js v— Reflecting on Mistakes


部分预渲染的工作原理

该功能本身是六个月前在候选版本中作为实验性 API 引入的。此 API 将保持这种状态,我们可能只会在版本 16 中看到它稳定(这很好,因为主要功能通常会在六个月到一年内过渡到稳定)。

关于更改。前面说过,主要是更新了工作原理。不过,从使用PPR的角度来看,这几乎没有什么影响。同时,它还获得了多项改进:

以前,配置中只有一个标志,但现在要启用 PPR,您需要指定“增量”。这样做显然是为了让逻辑更加透明 - 即使在 PPR 中,开发者也可以缓存内容,并且要更新它,您需要调用 revalidate 方法。

import { cookies } from 'next/headers';

export async function AdminPanel() {
  const cookieStore = await cookies();
  const token = cookieStore.get('token');

  // ...
}

另外,之前PPR是针对整个项目启动的,但现在需要针对每个分段(布局或页面)启用:

const nextConfig = {
  images: {
    localPatterns: [
      {
        pathname: '/assets/images/**',
        search: 'v=1',
      },
    ],
  },
}

另一个变化是部分回退预渲染(PFPR)。正是由于这一改进,预构建的部分立即发送到客户端,而其余部分则动态加载。在此期间,会显示回调组件来代替动态元素。

import Form from 'next/form'

export default function Page() {
  return (
    
; {/* On submission, the input value will be appended to the URL, e.g. /search?query=abc */} ; ;
; ) }

仪器仪表

Instrumentation 被标记为稳定的 API。检测文件允许用户挂钩 Next.js 服务器的生命周期。它适用于整个应用程序(包括 Pages Router 和 App Router 的所有部分)。

目前,instrumentation 支持以下钩子:

register - 初始化 Next.js 服务器时调用一次。它可用于与可观测性库(OpenTelemetry、datadog)集成或用于特定于项目的任务。

onRequestError - 为所有服务器错误调用的新挂钩。它可用于与错误跟踪库(Sentry)集成。

const nextConfig = {
  experimental: {
    turbo: {
      treeShaking: true,
      memoryLimit: 1024 * 1024 * 512 // in bytes / 512MB
    },
  },
}

拦截器

拦截器,也称为路由级中间件。它类似于一个成熟的[已经存在的]中间件,但与后者不同:

  • 它可以在 Node.js 运行时运行;
  • 它在服务器上工作(这意味着它可以访问环境和统一缓存);
  • 可以多次添加,嵌套继承(类似于中间件测试版时的工作方式);
  • 它也适用于服务器功能。

此外,当创建拦截器文件时,树中下面的所有页面都会变成动态的。

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

说到 Vercel,中间件现在将作为 CDN 级别的主要简单检查而有效(因此,例如,如果请求不被允许,则立即返回重定向),而拦截器将在服务器,执行全面的检查和复杂的操作。

然而,在自托管中,这样的划分显然效率较低(因为两个抽象都在服务器上工作)。仅使用拦截器可能就足够了。

结论

覆盖提取、激进的缓存、大量错误以及忽略社区请求。 Next.js 团队做出了错误的决定,仓促发布,并且不顾社区反馈坚持自己的观点。花了将近一年的时间才认识到这些问题。直到现在,终于,人们感觉到该框架再次解决了社区问题。

另一方面,还有其他框架。一年前,在 React.js 演示中,似乎所有框架都将很快与 Next.js 相提并论。 React 开始较少提及 Next.js 作为主要工具,框架展示了即将推出的构建系统、对服务器组件和功能的支持以及一系列全局更改和集成。时间已经过去了,基本上,他们还没有达到那个地步。

当然,最终的结论要过一段时间才能得出,但目前看来,React.js 的变化并没有达到预期的框架水平,反而导致了 Next.js 的更大统治地位,框架之间的差异更大(因为服务器组件和操作的实现由框架自行决定)。

同时,OpenAI 改用 Remix(“因为它具有更高的稳定性和便利性”):

Next.js v— Reflecting on Mistakes


在 ChatGPT 中重新混合使用

显然他们在 Next.js 发生重大变化之前就开始了

Next.js v— Reflecting on Mistakes


有关 ChatGPT 从 2024 年 8 月起切换为 Remix 的推文

总的来说,在接下来的 stateofjs 和 stackoverflow 调查中,我们很可能会看到重大的洗牌。

制作人员

代码示例或其基础取自 next.js 文档、提交、PR 和 next.js 核心;

后记

如果您需要一个基于 MD 文件生成文档的工具 - 请查看 robindoc.com,如果您使用 next.js - 您可能会在 nimpl.tech 的解决方案中找到有用的东西。

以上是Next.js v——反思错误的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:开发人员的比较分析Python vs. JavaScript:开发人员的比较分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

Python vs. JavaScript:选择合适的工具Python vs. JavaScript:选择合适的工具May 08, 2025 am 12:10 AM

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript:了解每个的优势Python和JavaScript:了解每个的优势May 06, 2025 am 12:15 AM

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

JavaScript的核心:它是在C还是C上构建的?JavaScript的核心:它是在C还是C上构建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript应用程序:从前端到后端JavaScript应用程序:从前端到后端May 04, 2025 am 12:12 AM

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。