跳到内容
返回博客

2022 年 12 月 22 日,星期四

Next.js 13.1

发布者

Next.js 13.1 包含了对 pages/ (稳定版) 和 app/ (测试版) 目录的改进

立即运行以下命令更新

终端
npm i next@latest react@latest react-dom@latest eslint-config-next@latest

改进了 app 目录的可靠性和支持

在 Next.js 13 中,我们发布了新的 app 目录(测试版)。这个新的路由和数据获取系统可以与您现有的 pages 目录一起逐步采用。

app 目录提供了许多优势,包括增强的布局、组件、测试和样式的同地协作、组件级数据获取等等。感谢您的反馈和早期测试,我们对 app 目录的可靠性进行了一些改进

  • 无布局 Div: 以前,当导航时,app 目录会添加额外的 <div> 元素以将布局滚动到视图中。在 13.1 中,不再创建这些额外的元素。滚动行为得以保留。
  • TypeScript 插件: 我们构建了一个新的 TypeScript 插件,它为页面和布局配置选项提供建议,将文档直接引入您的 IDE,并围绕服务器和客户端组件提供有用的使用提示(例如,防止在服务器组件中使用 useState)。了解更多
  • 可靠性改进: 我们修复了许多错误,包括改进的 CSS 模块支持,正确地为布局和页面去重 cache()fetch(),内存泄漏等等。
  • 更少的客户端 JavaScript:pages 目录相比,app 目录现在包含的客户端 JavaScript 减少了 9.3kB。无论您向应用程序添加 1 个还是 1000 个服务器组件,此基线都不会增加。React 运行时暂时略大,增加的原因是 React 服务器组件运行时,它处理 Next.js 以前处理的机制。我们正在努力进一步减少这种情况。
pages/app/增量
总首次加载 JS基线-9.3kB12.1% 更小
Next.js 运行时基线-12kB56.8% 更小
React 运行时基线+2.7kB5.2% 更大

我们很高兴继续在 app 目录的稳定性方面取得进展。关于 app 目录的 测试版文档 已根据您的 反馈 进行了数百次更新。

内置模块转译(稳定版)

您现在可以将来自本地包(如 monorepos)或外部依赖项 (node_modules) 的依赖项标记为需要转译和打包。这种内置支持取代了流行的 next-transpile-modules 包。

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
};
 
module.exports = nextConfig;

我们感谢 Pierre de la Martinière (@martpie) 在此包上的工作,以及他们在帮助确保内置支持满足社区需求方面提供的帮助。

导入解析以获得更小的包

许多流行的 npm 包使用 “barrel 文件” 来提供一个重新导出其他模块的单一文件。例如

@acme/ui/index.ts
export { default as Button } from './dist/Button';
export { default as Slider } from './dist/Slider';
export { default as Dropdown } from './dist/Dropdown';

这允许包的使用者在一行中使用命名导出

import { Button, Slider, Dropdown } from '@acme/ui';

虽然打包器理解这些 barrel 文件,并且可以删除未使用的重新导出(称为 “死代码消除”),但此过程涉及解析/编译所有重新导出的文件。对于已发布的库,某些 npm 包提供的 barrel 文件重新导出了数千个模块,这会减慢编译速度。这些库推荐使用 babel-plugin-transform-imports 来避免此问题,但对于那些使用 SWC 的用户来说,以前没有支持。我们已在 Next.js 中添加了一个新的 SWC 转换,称为 modularizeImports

这个新设置启用了 SWC 转换,它会根据定义的模式更改您的导入语句。例如,上面使用三个组件的代码将自动转换为使用直接导入,而无需开发人员手动编写此代码

// Before (with barrel file)
import { Button, Slider, Dropdown } from '@acme/ui';
 
// After (with modularized imports from plugin)
import Button from '@acme/ui/dist/Button';
import Slider from '@acme/ui/dist/Slider';
import Dropdown from '@acme/ui/dist/Dropdown';

可以通过 next.config.js 中的 modularizeImports 选项实现此转换

next.config.js
module.exports = {
  modularizeImports: {
    '@acme/ui': {
      transform: '@acme/ui/dist/{{member}}',
    },
  },
};

将此转换与 @mui/icons-materiallodash 结合使用可以跳过编译未使用的文件。了解更多

观看演示 以查看实际效果。

用于边缘的轻量级 Node.js 运行时,现在 API 路由已稳定

Next.js 内部的 Edge Runtime 使用 Node.js API 的严格子集(例如 RequestResponse 等),这些 API 与 Vercel 等边缘计算平台或自托管兼容。这些 API 在任何地方运行,包括在浏览器中,允许开发人员学习一次并在任何地方编写。

pages/api/hello.ts
// "experimental-" prefix is no longer needed
export const config = {
  runtime: 'edge',
};
 
export default function handler(req: Request) {
  return new Response('Hello World');
}

Next.js Middleware 已经默认使用这种轻量级边缘运行时以获得更好的性能。由于 Middleware 可以在应用程序中的每个请求之前运行,因此拥有轻量级运行时对于确保低延迟至关重要。在 Next.js 12.2 中,我们添加了可选地为 API 路由 使用此运行时的功能。

在 13.1 中,Next.js 内部的 Edge Runtime 对于 API 路由现在已稳定。当自托管时,使用 Edge Runtime 的 Middleware 和 API 路由将默认作为单区域工作负载运行,作为 next start 的一部分。在 Vercel 上,Next.js Middleware 和 API 路由使用 Vercel Edge Functions 全球部署,以实现尽可能低的延迟。Vercel Edge Functions 也 现已正式发布

Turbopack 改进

在 Next.js 13 中发布 Turbopack alpha 版本后,我们一直专注于提高可靠性、添加对最需要的功能的支持,并定义插件计划以及在其他框架中的使用。

自 Next.js 13.0.0 以来,Turbopack

  • 支持 PostCSS,包括 Tailwind CSS
  • 支持 next/image
  • 支持 @next/font (Google Fonts)
  • 支持从动态 import() 语句加载 CSS
  • 支持 CSS source maps(感谢 @ahabhgk贡献
  • 改进了 next dev 错误覆盖中的错误处理
  • 改进了内存使用
  • 改进了 CSS 模块支持
  • 改进了 HMR 更新的 chunking 算法
  • 提高了 HMR source maps 的可靠性

我们感谢 Evan You 和 Vite 社区提供的反馈和贡献,以确保 Turbopack 基准测试尽可能准确。我们与 Vite 团队合作验证了最新的 Turbopack 基准测试,并对我们的测试方法进行了许多改进。

由于这种合作,我们现在使用更准确的指标,包括在 React 更新机制中花费的时间。我们在 Turbopack 以及 webpack 上的 Next.js 13.1 中将 React Fast Refresh 时间缩短了 30 毫秒。我们还为使用 SWC 的 Vite 添加了一个新的基准测试,与使用默认的带有 Babel 的 Vite 相比,它显示出改进的性能。查看 更新后的基准测试 或阅读关于 测试方法

立即在 Next.js 13 中使用 next dev --turbo 试用 Turbopack alpha 版本。如果您有任何反馈,请在 GitHub 讨论 中告诉我们。

Next.js 高级 Middleware

感谢您的反馈,我们正在使 Next.js Middleware 比以往任何时候都更强大。在 13.1 中,您现在可以从 Middleware 返回响应,以及在请求上设置标头。

这些 API 改进为您提供了强大的新灵活性,可以自定义 Next.js 路由生命周期的每个部分。不再需要 next.config.js 中的 experimental.allowMiddlewareResponseBody 配置选项。

您现在可以更轻松地在请求上设置标头,以及直接响应,而无需 rewriteredirect

middleware.ts
import { NextResponse } from 'next/server';
 
export function middleware(request: Request) {
  // Check if a user has access...
  if (!isAuthorized(request)) {
    return NextResponse.json({ message: 'Unauthorized' });
  }
 
  // Add a new header, this will change the incoming request headers
  // that you can read in getServerSideProps and API routes
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13.1');
 
  return NextResponse.next({
    request: {
      // Apply new request headers
      headers: requestHeaders,
    },
  });
}

了解更多关于 Next.js 高级 Middleware 的信息。

其他改进

  • @next/font 现在支持在同一个字体声明中添加多个字体粗细和样式。了解更多
  • next/dynamic 现在使用 React 原语 lazy()<Suspense>。不再需要以前的 suspense 选项。通过这些更改,next/dynamic 现在与 app 目录兼容。
  • create-next-app 已更新为新设计,现在默认包含 @next/font,用于自动自托管字体,实现零布局偏移。使用 npx create-next-app@latest 试用,或部署模板
  • 我们对 App Directory Playground 进行了许多改进,它展示了 Next.js 13 中 app 目录(测试版)的一些最新功能和约定。部署您自己的
  • 我们创建了一个 高性能图像画廊模板,其中包括图像占位符、懒加载、自动优化、键盘支持等等。部署您自己的
  • 我们创建了一个资源,用于理解如何将 大型开源 React 和 Express.js 应用程序 迁移到 Next.js,包括详细的演练和指向特定提交的链接。

社区

Next.js 是超过 2,400 位个人开发者、Google 和 Meta 等行业合作伙伴以及我们在 Vercel 的核心团队共同努力的成果。凭借每周超过 360 万次的 npm 下载量和 97,900 多个 GitHub 星星,Next.js 是构建 Web 最流行的方式之一。

加入 GitHub DiscussionsRedditDiscord 社区。

此版本由以下人员为您带来

以及以下贡献者: @aarnadlr, @aaronbrown-vercel, @aaronjy, @abayomi185, @ademilter, @adictonator, @adilansari, @adtc, @alantoa, @aleksa-codes, @alfred-mountfield, @alpha-xek, @andarist, @andykenward, @anujssstw, @artdevgame, @artechventure, @arturbien, @aziyatali, @bennettdams, @bertho-zero, @blue-devil1134, @bot08, @brkalow, @brvnonascimento, @chanceaclark, @chibicode, @chrisipanaque, @chunsch, @colinking, @craigwheeler, @ctjlewis, @cvolant, @danmindru, @davidnx, @delbaoliveira, @devvspaces, @dtinth, @ducanhgh, @duncanogle, @ethomson, @fantaasm, @feugy, @fomichroman, @gruz0, @haschikeks, @hughlilly, @idoob, @iiegor, @imranbarbhuiya, @ingovals, @inokawa, @ishaqibrahimbot, @ismaelrumzan, @jakemstar, @janicklas-ralph, @jaredpalmer, @jaykch, @jimcresswell, @joliss, @josephcsoti, @joshuaslate, @joulev, @jueungrace, @juliusmarminge, @karlhorky, @kikobeats, @kleintorres, @koenpunt, @koltong, @kosai106, @labyrinthitis, @lachlanjc, @laityned, @leerob, @leoortizz, @lorenzobloedow, @lucasassisrosa, @m7yue, @manovotny, @marcus-rise, @matthew-heath, @mattpr, @maxleiter, @maxproske, @meenie, @mmaaaaz, @mnajdova, @moetazaneta, @mrkldshv, @nathanhammond, @nekochantaiwan, @nfinished, @niedziolkamichal, @nocell, @notrab, @nuta, @nutlope, @obusk, @orionmiz, @peraltafederico, @reshmi-sriram, @reyrodrigez, @rightones, @rishabhpoddar, @saseungmin, @serkanbektas, @sferadev, @silvioprog, @sivtu, @soonoo, @sqve, @steven-tey, @sukkaw, @superbahbi, @teobler, @theevilhead, @thomasballinger, @timeyoutakeit, @valentinh, @ws-jm, @wxh06, @yasath, @yutsuten, 和 @zekicaneksi。