Backブログに戻る

Next.js 12

Next.js 12では、新たなRustコンパイラ、ミドルウェア(ベータ版)、React 18サポート、ネイティブESMサポート、URLインポート、Reactサーバーコンポーネント(アルファ版)などが導入されました!

Next.js Confで発表したように、Next.js 12はこれまでで最大のリリースです:

今すぐアップデートするには npm i next@latest を実行してください。

Rustコンパイラによる高速なビルドとFast Refresh

Next.jsでは、すべてのアプリケーションの本番ビルドをより高速にし、ローカル開発では即時のフィードバックを得られるようにしたいと考えています。Next.js 12には、ネイティブコンパイルを活用した新しいRustコンパイラが含まれています。

私たちのRustコンパイラは、次世代の高速ツールのためのオープンプラットフォームであるSWCを基盤としています。ローカルでは約3倍高速なFast Refresh、本番環境では約5倍高速なビルドを実現しました。その他の改善点と機能には以下が含まれます:

大規模なNext.jsコードベースで新しいRustコンパイラを使用した結果

大規模なNext.jsコードベースで新しいRustコンパイラを使用した結果

  • 大規模コードベースのさらなる高速化: 世界最大級のNext.jsコードベースでRustコンパイラを検証しました。
  • パフォーマンスの可観測性向上: Next.jsは現在、クライアントとサーバーのコンパイルについて、コンパイルされたモジュールとファイルの数を含むFast Refreshのタイミングをコンソールに出力します。
  • 基盤となるwebpackの改善: Fast Refreshの最適化やオンデマンドエントリの信頼性向上など、webpackに多数の改良を加えました。

Rustを使用したコンパイルはBabelよりも17倍高速で、Next.js 12ではデフォルトで有効になっており、JavaScriptとTypeScriptファイルの変換に代わります。これには、Next.jsのBabel変換をRustに移植する必要があり、styled-jsx変換を実装するために使用されるRustで書かれた新しいCSSパーサーも含まれます。

新しいRustコンパイラは後方互換性があります。既存のBabel設定がある場合、自動的にオプトアウトされます。styled-componentsemotionrelayなどの人気ライブラリのパースも近々移植予定です。カスタムBabel設定を使用している場合は、設定を共有してください

また、Rustコンパイラを使用したミニフィケーションもオプトインで利用できます。これはTerserよりも7倍高速です。ミニフィケーションは、長年にわたるインフラを置き換えるため、十分に検証されるまでオプトインとなります。

next.config.js
module.exports = {
  swcMinify: true,
};

SWCの作成者であるDongYoon KangParcelの貢献者であるMaia Teegardenを採用したことに加え、私たちはRustエコシステムへの投資を続けています。Rustの経験がある方は、ぜひチームに参加してください

詳細については、Next.js Confのデモ動画をご覧ください

ミドルウェアの紹介

ミドルウェアを使用すると、設定よりもコードを優先できます。これにより、リクエストが完了する前にコードを実行できるため、Next.jsで完全な柔軟性が得られます。ユーザーの受信リクエストに基づいて、リライト、リダイレクト、ヘッダーの追加、HTMLのストリーミングなどでレスポンスを変更できます。

ミドルウェアはNext.js内で完全な柔軟性を提供します

ミドルウェアはNext.js内で完全な柔軟性を提供します

ミドルウェアは、以下のようなページセットに共有ロジックが必要なあらゆる場面で使用できます:

ミドルウェアは、**fetch**などの標準Web APIをサポートする厳格なランタイムを使用します。これはnext startでそのまま動作し、Edge Middlewareを使用するVercelなどのエッジプラットフォームでも動作します。

Next.jsでミドルウェアを使用するには、pages/_middleware.jsファイルを作成します。この例では、標準のWeb API Response(MDN)を使用しています:

pages/_middleware.js
export function middleware(req, ev) {
  return new Response('Hello, world!');
}

詳細については、Next.js Confのデモ動画をご覧くださいし、ドキュメントを確認してください

React 18への準備

React 18では、Suspense、更新の自動バッチ処理、startTransitionのようなAPI、およびReact.lazyをサポートしたサーバーサイドレンダリングのための新しいストリーミングAPIなどの機能が追加されます。

私たちは、安定版リリースに向けてReact 18のNext.js対応をFacebookのReactチームと緊密に協力して準備しています。これらの機能は、Next.js 12で実験的なフラグの下で今日から試用可能です。

Terminal
npm install react@alpha react-dom@alpha

サーバーサイドストリーミング

React 18のコンカレント機能には、サーバーサイドSuspenseとSSRストリーミングサポートの組み込みサポートが含まれます。これにより、HTTPストリーミングを使用してページをサーバーレンダリングできます。これはNext.js 12の実験的な機能ですが、有効にすると、SSRはミドルウェアと同じ厳格なランタイムを使用します。

有効にするには、実験的フラグconcurrentFeatures: trueを使用します:

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
  },
};

React Server Components (Reactサーバーコンポーネント)

React Server Components (RSC) を使用すると、コンポーネント自体を含むすべてをサーバー上でレンダリングできます。これは、サーバー上でHTMLを事前生成するサーバーサイドレンダリング (SSR) とは根本的に異なります。Server ComponentsではクライアントサイドのJavaScriptが一切不要であり、ページのレンダリングが高速化されます。これにより、サーバーレンダリングの利点とクライアントサイドのインタラクティブ性を組み合わせた優れたユーザー体験が実現します。

next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true,
  },
};

Next.jsでは現在、_コンポーネントレベル_でのデータ取得が可能で、すべてJSXとして表現されます。React Server Componentsを使用することで、getServerSidePropsgetStaticPropsのような特別な関数が不要になり、簡素化されます。これは、データ取得をコンポーネントと共に配置するReact Hooksのモデルに沿っています。

Next.jsのページを.server.jsにリネームすることでServer Componentを作成でき、Server Components内で直接クライアントコンポーネントをインポートできます。これらのクライアントコンポーネントはハイドレートされインタラクティブになるため、例えば「いいね」機能などを追加できます。

現在、Next.jsではサーバーサイドのSuspense、選択的ハイドレーション、ストリーミングレンダリングに取り組んでおり、進捗は今後のブログ記事で共有する予定です。

React 18とServer Componentsに関する協力に感謝します: Google AuroraチームのKara EricksonGerald Monaco

詳細は、Next.js Confのデモ動画ドキュメントをご覧ください。

ES ModulesのサポートとURLインポート

ESモジュールはJavaScriptに公式で標準化されたモジュールシステムをもたらします。主要なブラウザとNode.jsでサポートされています。

この標準により、パッケージサイズとJavaScriptバンドルが小さくなり、最終的にはより良いユーザー体験が実現します。JavaScriptエコシステムがCommon JS(旧標準)からESモジュールへ移行する中、私たちは開発者が段階的にこれらの改善を採用できるよう、不必要な破壊的変更を避けることに注力しています。

Next.js 11.1から、CommonJSモジュールより優先されるESモジュールの実験的サポートを追加しました。Next.js 12ではこれがデフォルトとなりました。CommonJSのみを提供するNPMモジュールのインポートも引き続きサポートされます。

URLインポート

Next.js 12では、URL経由でESモジュールをインポートする実験的サポートが追加されました。インストールや別途ビルドステップは不要です。

URLインポートにより、URLから_任意の_パッケージを直接使用できます。これによりNext.jsはリモートのHTTP(S)リソースをローカルの依存関係と同様に処理できます。

URLインポートが検出されると、Next.jsはリモートリソースを追跡するnext.lockファイルを生成します。URLインポートはローカルにキャッシュされるため、オフラインでも作業可能です。クライアントとサーバーの両方のURLインポートをサポートしています。

有効化するには、next.config.jsで許可するURLプレフィックスを追加します:

next.config.js
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev'],
  },
};

その後、URLから直接モジュールをインポートできます:

import confetti from 'https://cdn.skypack.dev/canvas-confetti';

ESモジュールを提供する任意のCDNが動作します。Framerのようなノーコード/デザインツールも含みます:

詳細は、Next.js Confのデモ動画ドキュメントをご覧ください。

ボット対応ISRフォールバック

現在、Incremental Static Regeneration (ISR)fallback: trueを使用すると、まだ生成されていないページへの最初のリクエスト時に、ページコンテンツをレンダリングする前にフォールバック状態が表示されます。ページの読み込みをブロック(サーバーレンダリング)するには、fallback: 'blocking'を使用する必要がありました。

Next.js 12では、ウェブクローラー(検索ボットなど)fallback: trueを使用するISRページを自動的にサーバーレンダリングするようになり、非クローラーのUser-Agentには従来のフォールバック状態の動作を維持します。これにより、クローラーがローディング状態をインデックスするのを防ぎます。

AVIFによるより小さな画像

組み込みのImage Optimization APIがAVIF画像をサポートし、WebPと比べて20%小さな画像が可能になりました。

AVIF画像はWebPに比べて最適化に時間がかかるため、next.config.jsの新しいimages.formatsプロパティを使用してオプトイン方式としています:

next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};

このフォーマットリストは、リクエストのAcceptヘッダーを使用してオンデマンドで最適化された画像フォーマットを決定するために使用されます。AVIFが最初にリストされているため、AVIFをサポートするブラウザではAVIFが提供されます。サポートしていない場合、WebPをサポートするブラウザではWebPが提供されます。どちらのフォーマットもサポートしていない場合、元の画像フォーマットが提供されます。

出力ファイルトレーシング

Next.js 8でtargetオプションを導入しました。これはビルド時にwebpackを使用してすべての依存関係をバンドルし、Next.jsページをスタンドアロンJavaScriptバンドルとして出力するものでした。しかしこれは理想的でないことがわかり、代わりに@vercel/nftを作成しました。@vercel/nftはVercelプラットフォーム上のすべてのデプロイで2年以上使用されています。

今回、これらの改善をNext.jsフレームワークに直接組み込み、すべてのデプロイプラットフォームで、targetオプションよりも大幅に改善されたアプローチを提供します。

Next.js 12は@vercel/nftを使用して、各ページとAPIルートに必要なファイルを自動的にトレースし、next build出力の隣にトレース結果を出力します。これにより、インテグレーターはNext.jsが自動的に提供するトレースを活用できます。

これらの変更は、next startを使用したDockerなどでのアプリケーションデプロイも最適化します。@vercel/nftを活用することで、将来的にはNext.jsの出力をスタンドアロンにできるようになります。アプリケーションの実行に必要な依存関係をインストールする必要がなくなり、Dockerイメージサイズを大幅に削減できます。

@vercel/nftをNext.jsに組み込むことで、targetアプローチは廃止され、Next.js 12では非推奨となります。詳細はドキュメントをご覧ください。

その他の改善点

  • pages/_app.jsまたはpages/_document.jsをアプリケーションに追加すると、Next.js CLIの再起動なしに自動的に組み込みバージョンが置き換えられます。
  • ESLint統合で、next lint--fileフラグを使用したシングルファイルリンティングをサポート。
  • Next.js 12でカスタムtsconfig.jsonパスの設定をサポート。
  • 設定をESモジュールとして記述するnext.config.mjsをサポート。
  • getStaticPropsでの重複したインフライトリクエストを排除。
  • 静的ページのチェックが共有ワーカープールを使用して実行されるように。
  • Fast RefreshがEventSource接続の代わりにWebSocket接続を使用するように。

破壊的変更

  • Next.js 11でwebpack 5をデフォルトにした後、webpack 4を正式に削除しました。コミュニティと緊密に連携し、webpack 5へのスムーズな移行を確保しました。
  • next.config.jstargetは不要になりました。
  • next/imageのラッピング要素がdivからspanに変更されました。
  • 最小Node.jsバージョンが12.0.0からネイティブESモジュールをサポートする最初のバージョンである12.22.0に引き上げられました。

詳細は、アップグレードガイドをご覧ください。

コミュニティ

5年前、Next.jsを公開しました。私たちは、開発者体験を簡素化するゼロコンフィギュレーションのReactフレームワークを構築することを目指しました。振り返ると、コミュニティの成長と共に実現してきたことに驚かされます。この調子で進み続けましょう。

Next.jsは、1,800人以上の個人開発者、GoogleやFacebookなどの業界パートナー、そして私たちのコアチームの共同作業の結果です。

このリリースには以下の方々の貢献がありました: @ka2n, @housseindjirdeh, @rojserbest, @lobsterkatie, @thibautsabot, @javivelasco, @sokra, @rishabhpoddar, @kdy1, @huozhi, @georgegach, @ionut-botizan, @paul-creates, @TimBarley, @kimizuy, @devknoll, @matamatanot, @christianvuerings, @pgrodrigues, @mohamedbhy, @AlfonzAlfonz, @kara, @molebox, @angelopoole, @oste, @genetschneider, @jantimon, @kyliau, @mxschmitt, @PhattOZ, @finn-orsini, @kriswuollett, @harryheman, @GustavoEdinger, @AryanBeezadhur, @Blevs, @colevscode, @atcastle, @ijjk, @velocity23, @jonowu, @timneutkens, @whitep4nth3r, @micro-chipset, @TyMick, @padmaia, @arthurdenner, @vitorbal, @zNeb, @jacksonhardaker, @shuding, @kylemh, @Bundy-Mundi, @ctjlewis, @thien-do, @leerob, @Dev-CasperTheGhost, @janicklas-ralph, @rezathematic, @KonstHardy, @fracture91, @lorensr, @Sheraff, @HaNdTriX, @emilio, @oluan, @ddzieduch, @colinclerk, @x4th, @volcareso, @oiva, @sinchang, @scottrepreneur, @smakosh, @catnose99, @adrienharnay, @donsn, @andersonleite, @msp5382, @tim-hanssen, @appsplash99, @alexvilchis, @RobEasthope, @royal, @Perry-Olsson, @well-balanced, @mrmckeb, @buraksakalli, @espipj, @prateekbh, @AleksaC, @eungyeole, @rgabs