2021年10月26日 火曜日
Next.js 12
投稿者Next.js Confで発表した通り、Next.js 12はこれまでで最大のリリースです。
- Rustコンパイラ: Fast Refreshが約3倍高速化し、ビルドが約5倍高速化
- Middleware (ベータ版): 設定ではなくコードによるNext.jsの完全な柔軟性を実現
- React 18のサポート: ネイティブNext.js APIとSuspenseがサポートされました
<Image />
AVIFサポート: 20%小さい画像を実現 (オプトイン)- ボット対応ISRフォールバック: ウェブクローラー向けSEOを最適化
- ネイティブESモジュールサポート: 標準化されたモジュールシステムに準拠
- URLインポート (アルファ版): どのURLからもパッケージをインポート可能、インストール不要
- React Server Components (アルファ版): 今すぐ試用可能、SSRストリーミングを含む
本日、npm i next@latest
を実行してアップデートしてください。
Rustコンパイラによる高速なビルドとFast Refresh
すべてのNext.jsアプリケーションのプロダクションビルドを高速化し、ローカル開発で即座にフィードバックを得たいと考えています。Next.js 12には、ネイティブコンパイルを活用する全く新しいRustコンパイラが含まれています。
当社のRustコンパイラは、次世代の高速なツールプラットフォームであるSWC上に構築されています。ローカルでのリフレッシュは約3倍、プロダクション向けビルドは約5倍高速化されました。その他の改善点と機能には以下が含まれます。

- 大規模コードベース向けのさらなる高速化: 世界最大規模の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-components
、emotion
、relay
などの人気ライブラリのパースは、まもなく移植する予定です。カスタムのBabelセットアップを使用している場合は、設定を共有してください。
ミニファイのためにRustコンパイラを使用することもできます。これはTerserより7倍高速です。ミニファイは、長年のインフラを置き換えるため、十分に検証されるまではオプトインとなります。
module.exports = {
swcMinify: true,
};
SWCの作成者であるDongYoon Kangと、Maia Teegarden(Parcelへのコントリビューター)を雇用することに加え、当社はRustエコシステムへの投資を継続しています。Rustでの開発経験をお持ちの方は、ぜひチームへの参加をご応募ください。
詳細については、Next.js Confでのデモをご覧ください。
Middlewareの導入
Middlewareを使用すると、設定ではなくコードで対応できるようになります。これにより、リクエストが完了する前にコードを実行できるため、Next.jsで完全な柔軟性が得られます。ユーザーからのリクエストに基づいて、書き換え、リダイレクト、ヘッダーの追加、さらにはHTMLのストリーミングによってレスポンスを変更できます。

Middlewareは、一連のページでロジックを共有するあらゆる目的に使用できます。これには以下が含まれます。
- 認証
- ボット保護
- リダイレクト
- リライト
- フィーチャーフラグとA/Bテスト
- 高度なi18nルーティング要件
- その他にも!
Middlewareは、fetch
などの標準Web APIをサポートする厳格なランタイムを使用します。これはnext start
を使用してすぐに機能し、Edge Middlewareを使用するVercelのようなEdgeプラットフォームでも機能します。
Next.jsでMiddlewareを使用するには、pages/_middleware.js
ファイルを作成します。この例では、標準のWeb API Response(MDN)を使用します。
export function middleware(req, ev) {
return new Response('Hello, world!');
}
詳細については、Next.js Confでのデモをご覧くださいと、ドキュメントをご確認ください。
React 18への準備
React 18では、Suspense、自動更新バッチング、startTransition
のようなAPI、そしてReact.lazy
をサポートするサーバーレンダリング用の新しいストリーミングAPIといった機能が追加されます。
FacebookのReactチームと密接に協力し、React 18の安定版リリースに向けてNext.jsの準備を進めてきました。Next.js 12では、これらの機能を実験的フラグの下で今すぐお試しいただけます。
npm install react@alpha react-dom@alpha
サーバーサイドストリーミング
React 18の並行機能には、サーバーサイドのSuspenseの組み込みサポートとSSRストリーミングサポートが含まれています。これにより、HTTPストリーミングを使用してページをサーバーレンダリングできます。これはNext.js 12の実験的な機能ですが、有効にするとSSRはMiddlewareと同じ厳格なランタイムを使用します。
有効にするには、実験的フラグconcurrentFeatures: true
を使用してください。
module.exports = {
experimental: {
concurrentFeatures: true,
},
};
React Server Components
React Server Componentsを使用すると、コンポーネント自体を含め、すべてをサーバー上でレンダリングできます。これは、サーバーでHTMLを事前に生成するサーバーサイドレンダリングとは根本的に異なります。Server Componentsでは、クライアントサイドのJavaScriptが一切不要で、ページのレンダリングが高速化されます。これにより、サーバーレンダリングの最高の部分とクライアントサイドのインタラクティブ性を組み合わせることで、アプリケーションのユーザーエクスペリエンスが向上します。
module.exports = {
experimental: {
concurrentFeatures: true,
serverComponents: true,
},
};
Next.jsでは、JSXとしてすべて表現された、コンポーネントレベルでのデータフェッチングが可能になりました。React Server Componentsを使用することで、物事を簡素化できます。getServerSideProps
やgetStaticProps
のような特別な関数はもはや不要です。これは、データフェッチングをコンポーネントと併置するReact Hooksのモデルに沿っています。
任意のNext.jsページを.server.js
にリネームすることで、Server Componentを作成し、クライアントコンポーネントをServer Components内に直接インポートできます。これらのクライアントコンポーネントはハイドレートされ、インタラクティブになるため、高評価のような機能を追加できます。
現在、Next.jsでのサーバーサイドSuspense、選択的ハイドレーション、ストリーミングレンダリングに取り組んでおり、今後のブログ記事で進捗を共有します。
React 18およびServer Componentsに関するGoogle Auroraチームの共同作業者であるKara EricksonとGerald Monacoに感謝します。
詳細については、Next.js Confでのデモをご覧くださいと、ドキュメントをご確認ください。
ESモジュールサポートとURLインポート
ESモジュールは、JavaScriptに公式かつ標準化されたモジュールシステムをもたらします。これらは主要なすべてのブラウザとNode.jsでサポートされています。
この標準は、パッケージサイズとJavaScriptバンドルの小型化を可能にすることでWebエコシステムを前進させ、最終的に優れたユーザーエクスペリエンスにつながります。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インポートはローカルにキャッシュされるため、オフラインでも作業を続けることができます。Next.jsはクライアントとサーバーの両方のURLインポートをサポートしています。
オプトインするには、許可された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フォールバック
現在、fallback: true
を使用したIncremental Static Regenerationは、まだ生成されていないページへの最初のリクエストでページコンテンツをレンダリングする前に、フォールバック状態をレンダリングします。ページの読み込み(サーバーレンダリング)をブロックするには、fallback: 'blocking'
を使用する必要があります。
Next.js 12では、ウェブクローラー(例:検索ボット)は、fallback: true
を使用してISRページを自動的にサーバーレンダリングしますが、クローラー以外のユーザーエージェントにはフォールバック状態の以前の動作を提供します。これにより、クローラーが読み込み状態をインデックスすることを防ぎます。
AVIFを使用したより小さい画像
組み込みの画像最適化APIがAVIF画像をサポートし、WebPと比較して画像を20%小さくできるようになりました。
AVIF画像はWebPと比較して最適化に時間がかかる場合があるため、この機能はnext.config.js
の新しいimages.formats
プロパティを使用してオプトインとしました。
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ではtarget
が非推奨となりました。詳細についてはドキュメントをご確認ください。
その他の改善
- アプリケーションに
pages/_app.js
またはpages/_document.js
を追加すると、Next.js CLIの再起動を必要とせずに、組み込みバージョンが自動的に置き換えられるようになりました。 - ESLint統合は、
next lint
で--file
フラグを使用して単一ファイルのリントをサポートするようになりました。 - Next.js 12は、カスタムの
tsconfig.json
パスの設定をサポートするようになりました。 next.config.mjs
は、設定をESモジュールとして記述するためにサポートされるようになりました。- getStaticPropsの進行中のリクエストが重複排除されるようになりました。
- 静的ページのチェックは、共有ワーカープールを使用して実行されるようになりました。
- Fast Refreshは、EventSource接続の代わりにWebSocket接続を使用するようになりました。
破壊的変更
- Next.js 11でwebpack 5をデフォルトにした後、正式にwebpack 4を削除しました。webpack 5へのスムーズな移行を確実にするため、コミュニティと密接に協力してきました。
next.config.js
のtarget
は不要になりました。next/image
は、ラッピング要素としてdiv
の代わりにspan
を使用するようになりました。- 最小Node.jsバージョンが
12.0.0
から12.22.0
に引き上げられました。これは、ネイティブESモジュールをサポートする最初のNode.jsバージョンです。
詳細については、アップグレードガイドをご確認ください。
コミュニティ
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, and @rgabs