跳到内容
返回博客

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` 目录会在导航时添加额外的 `
    ` 元素以将滚动布局带入视图。在 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` 目录的 测试版文档 已经根据 您的反馈 进行了数百次更新。

内置模块转译(稳定版)

您现在可以将来自本地包(例如 Monorepo)或外部依赖项(`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 包都使用“桶文件”来提供单个文件,该文件重新导出其他模块。例如:

@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';

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

此新设置启用 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}}',
    },
  },
};

利用 `modularizeImports` 对 `@mui/icons-material` 或 `lodash` 进行转换,可以跳过未使用文件的编译。了解更多

观看演示以了解其运作方式。

Edge 的轻量级 Node.js 运行时,现在 API 路由已稳定

Next.js 中的 Edge Runtime 使用 Node.js API(如 `Request`、`Response` 等)的严格子集,这些 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 中间件默认已经使用这个轻量级边缘运行时以获得更好的性能。由于中间件可以在应用程序中的每个请求之前运行,因此拥有一个轻量级运行时对于确保低延迟至关重要。在 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 字体)
  • 支持从动态 `import()` 语句加载 CSS
  • 支持 CSS 源映射(感谢 `@ahabhgk` 的贡献
  • 改进了 `next dev` 错误覆盖中的错误处理
  • 改善内存使用
  • 改进了 CSS 模块支持
  • 改进了 HMR 更新的分块算法
  • 提高了 HMR 源映射的可靠性

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

作为此次合作的成果,我们现在使用更准确的指标,其中包括 React 更新机制中花费的时间。我们成功将 Turbopack 和 Next.js 13.1 在 webpack 上的 React Fast Refresh 时间缩短了 30 毫秒。我们还为使用 SWC 的 Vite 添加了一个新基准,显示与使用默认 Vite 和 Babel 相比,性能有所提高。查看更新的基准测试或阅读有关测试方法的信息。

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

Next.js 高级中间件

感谢您的反馈,我们正在使 Next.js 中间件变得比以往任何时候都更加强大。通过 13.1 版本,您现在可以从中间件返回响应,并设置请求头。

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

现在,您可以更轻松地设置请求头,并直接响应而无需进行 `rewrite` 或 `redirect`

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.js 是 2,400 多名独立开发者、Google 和 Meta 等行业合作伙伴以及我们 Vercel 核心团队共同努力的成果。Next.js 每周 npm 下载量超过 360 万次,GitHub 星标超过 97,900 个,是构建 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。