跳到内容
返回博客

2022年12月22日,星期四

Next.js 13.1

发布者

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

立即运行以下命令更新

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

提升了 app 目录的可靠性和支持

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

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

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

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

内置模块转译 (稳定版)

现在,您可以将来自本地包 (如 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 files” 来提供一个重新导出其他模块的单一文件。例如

@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 与 Edge 计算平台 (如 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 中间件已经默认使用这种轻量级的 edge runtime 以获得更好的性能。由于中间件可以在应用程序中的每个请求之前运行,因此拥有轻量级的运行时对于确保低延迟至关重要。在 Next.js 12.2 中,我们添加了可选地将此运行时用于 API 路由 的功能。

在 13.1 中,Next.js 内部的 Edge Runtime 对于 API 路由现在是稳定的。当自托管时,使用 Edge Runtime 的中间件和 API 路由将默认作为 next start 的一部分以单区域工作负载运行。在 Vercel 上,Next.js 中间件和 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 毫秒。我们还添加了一个使用 Vite 和 SWC 的新基准测试,该测试显示与使用默认 Vite 和 Babel 相比,性能有所提高。查看 更新的基准测试 或阅读有关 测试方法 的更多信息。

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

Next.js 高级中间件

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

这些 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 高级中间件的信息。

其他改进

  • @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 目录 (beta 版) 的一些最新功能和约定。 部署您自己的
  • 我们创建了一个 高性能图像画廊模板,其中包括图像占位符、懒加载、自动优化、键盘支持等等。 部署您自己的
  • 我们创建了一个资源,用于了解如何将 大型开源 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。