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

2021年10月26日火曜日

Next.js 12

投稿者

昨日発表された Next.js Confでお知らせしたように、Next.js 12はこれまでにない最大のリリースです。

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

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

あらゆるNext.jsアプリケーションのプロダクションビルドを高速化し、ローカル開発での即時フィードバックを実現したいと考えています。Next.js 12には、ネイティブコンパイルを活用した全く新しいRustコンパイラが搭載されています。

当社のRustコンパイラは、次世代の高速ツールプラットフォームであるSWC上に構築されています。バンドルとコンパイルを最適化し、ローカルでのリフレッシュは約3倍速く、プロダクションビルドは約5倍速くなりました。その他の改善点と機能は以下の通りです。

Results from using the new Rust compiler with large Next.js codebases.
大規模Next.jsコードベースでの新しいRustコンパイラ使用結果。
  • 大規模コードベースでのさらなる速度向上: 世界最大級のNext.jsコードベースでRustコンパイラを検証しました。
  • パフォーマンスの監視性の向上: Next.jsは、クライアントおよびサーバーコンパイルの両方について、コンパイルされたモジュール数とファイル数を含むFast Refreshのタイミングをコンソールに出力するようになりました。
  • 基盤となるwebpackの改善: webpackに数多くの改善を加えました。Fast Refreshの最適化や、オンデマンドエントリの信頼性向上などです。

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

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

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

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

SWCの作成者であるDongYoon Kangと、Parcelへの貢献者であるMaia Teegardenを雇用したことに加え、Rustエコシステムへの投資を継続しています。Rustでの経験をお持ちの方は、チームへの参加を応募してください

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

ミドルウェアの紹介

ミドルウェアは、コードを直接実行することで設定よりも柔軟性を提供します。これにより、リクエストが完了する前にコードを実行できるため、Next.jsで完全な柔軟性を実現できます。ユーザーの受信リクエストに基づいて、リライト、リダイレクト、ヘッダーの追加、さらにはHTMLのストリーミングによってレスポンスを修正できます。

Middleware gives you complete flexibility inside Next.js.
ミドルウェアはNext.js内で完全な柔軟性を提供します。

ミドルウェアは、以下のような、一連のページでロジックを共有するあらゆるものに使用できます。

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

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、サーバーレンダリングのための新しいストリーミングAPI(React.lazyサポート付き)などの機能が追加されます。

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はミドルウェアと同じ厳格なランタイムを使用します。

有効にするには、実験的フラグconcurrentFeatures: trueを使用してください。

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

React Server Components

React Server Componentsは、コンポーネント自体を含むすべてをサーバーでレンダリングできるようにします。これは、サーバーでHTMLを事前生成するサーバーサイドレンダリングとは根本的に異なります。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 Component内にクライアントコンポーネントを直接インポートできます。これらのクライアントコンポーネントはハイドレートされ、インタラクティブになるため、アップボートのような機能を追加できます。

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

コラボレーターであるGoogle AuroraチームのKara EricksonGerald Monacoに特別な感謝を申し上げます。彼らはReact 18とServer Componentsに取り組んでいます。

詳細については、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インポートをサポートしています。

オプトインするには、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 Regenerationfallback: trueを使用すると、まだ生成されていないページへの最初のリクエスト時に、ページコンテンツをレンダリングする前にフォールバック状態がレンダリングされます。ページをブロックしてレンダリング(サーバーレンダリング)するには、fallback: 'blocking'を使用する必要があります。

Next.js 12では、ウェブクローラー(例: 検索ボット)fallback: trueを使用してISRページを自動的にサーバーレンダリングします。これにより、クローラーがローディング状態をインデックスに登録するのを防ぎます。

AVIFを使用した軽量画像

組み込みの画像最適化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をサポートしている場合に提供されます。サポートされていない場合は、ブラウザが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が自動的に提供するトレースを活用できます。

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

Next.jsに@vercel/nftを取り込むことは、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.jstargetは不要になりました。
  • 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, @rgabsの貢献によって提供されました。