コンテンツへスキップ
ブログに戻る

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プラグイン:ページとレイアウトの設定オプションに関する提案を提供し、ドキュメントをIDEに直接表示し、サーバーコンポーネントとクライアントコンポーネントに関する便利な使用方法のヒント(サーバーコンポーネントでのuseStateの使用を防ぐなど)を提供する新しいTypeScriptプラグインを構築しました。詳細はこちら
  • 信頼性の向上:CSSモジュールのサポートの改善、レイアウトとページのcache()fetch()の重複除去、メモリリークなど、多数のバグを修正しました。
  • クライアントサイドJavaScriptの削減:appディレクトリは、pagesディレクトリよりもクライアントサイド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ディレクトリのベータ版ドキュメントは、皆様からのフィードバックに基づいて数百回もアップデートされています(フィードバックに基づいて)。

組み込みモジュールトランスパイル(安定版)

ローカルパッケージ(モノレポなど)または外部依存関係(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変換が有効になります。たとえば、3つのコンポーネントを使用する上記のコードは、開発者が手動でこのコードを記述する必要なしに、自動的に直接インポートを使用するように変換されます。

// 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.jsmodularizeImportsオプションで可能です。

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

@mui/icons-materiallodashでこの変換を活用することで、使用されていないファイルのコンパイルをスキップできます。詳細はこちら

デモを見る これを実演で確認できます。

Edge向けの軽量なNode.jsランタイム、APIルートで安定版になりました

Next.js の Edge Runtime は、Vercel やセルフホスティング時など、エッジコンピューティングプラットフォームと互換性のある、Node.js API の厳格なサブセット(RequestResponse など)を使用します。これらの 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 は、パフォーマンス向上のため、既にデフォルトでこの軽量な Edge Runtime を使用しています。Middleware はアプリケーションのすべてのリクエストの前に実行できるため、低レイテンシを確保するには軽量な Runtime が不可欠です。Next.js 12.2 では、オプションでこの Runtime をAPI Routesにも使用できるようにしました。

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 アルファ版をリリースして以来、信頼性の向上、最も要望の多い機能のサポート追加、プラグインとその他のフレームワークでの使用計画の策定に重点を置いてきました。

Next.js 13.0.0 以降、Turbopack は

  • PostCSS(Tailwind CSS を含む)をサポート
  • next/image をサポート
  • @next/font(Google Fonts)をサポート
  • 動的な import() ステートメントからの CSS の読み込みをサポート
  • CSS ソースマップをサポート(ご貢献いただいた @ahabhgk さんに感謝いたします)
  • next dev エラーオーバーレイでのエラー処理の改善
  • メモリ使用量の改善
  • CSS モジュールのサポート改善
  • HMR 更新のためのチャンク化アルゴリズムの改善
  • HMR ソースマップの信頼性の向上

Turbopack のベンチマークの精度を可能な限り高めるため、Evan You 氏と Vite コミュニティからのフィードバックと貢献に感謝いたします。Vite チームと協力して最新の Turbopack ベンチマークを検証し、テスト方法を大幅に改善しました。

この協力の結果、React の更新メカニズムに費やされた時間も考慮した、より正確な指標を使用するようになりました。Turbopack と webpack を使用した Next.js 13.1 で、React Fast Refresh の時間を 30 ミリ秒改善することができました。また、SWC を使用した Vite の新しいベンチマークを追加しました。これは、Babel を使用したデフォルトの Vite と比較してパフォーマンスが向上していることを示しています。更新されたベンチマークをご覧ください、またはテスト方法についてお読みください。

next dev --turbo を使用して、Next.js 13 で Turbopack アルファ版を今すぐお試しください。フィードバックがありましたら、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/dynamicapp ディレクトリと互換性を持つようになりました。
  • create-next-app は新しいデザインで更新され、レイアウトシフトをゼロにするフォントの自動セルフホスティングのために、@next/font がデフォルトで含まれるようになりました。npx create-next-app@latest でお試しいただくか、テンプレートをデプロイしてください。
  • Next.js 13 の app ディレクトリ(ベータ版)の最新の機能と規則の一部を紹介するApp Directory Playgroundに多くの改善を加えました。独自のものを作成する
  • 画像プレースホルダー、遅延読み込み、自動最適化、キーボードサポートなどを含む高性能な画像ギャラリーテンプレートを作成しました。独自のものを作成する
  • 大規模なオープンソースの React と Express.js アプリケーションを Next.js に移行する方法を理解するためのリソースを作成しました。詳細な手順と特定のコミットへのリンクが含まれています。

コミュニティ

Next.js は、2400 人を超える個々の開発者、Google や Meta などの業界パートナー、そして Vercel のコアチームの共同作業の成果です。毎週 360 万回以上の npm ダウンロード数と 97,900 件以上の GitHub スターを獲得しており、Next.js は Web を構築する最も人気のある方法の 1 つです。

コミュニティに参加しましょう。 GitHub DiscussionsReddit、そしてDiscord

このリリースは、下記の方々によって実現されました。

そして、以下の方々からの貢献: @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。