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

2022年6月28日(火)

Next.js 12.2

投稿者

Next.jsの未来のための基盤を12.2で築いています。

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

ミドルウェア(安定版)

12.2でミドルウェアが安定版になったことを嬉しく思います。ユーザーからのフィードバックに基づいてAPIが改善されました。

ミドルウェアを使用すると、リクエストが完了する前にコードを実行できます。受信リクエストに基づいて、書き換え、リダイレクト、ヘッダーの追加、またはCookieの設定によってレスポンスを変更できます。

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
 
// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
  const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
  req.nextUrl.pathname = isInBeta ? '/beta' : '/';
  return NextResponse.rewrite(req.nextUrl);
}
 
// Supports both a single value or an array of matches
export const config = {
  matcher: '/',
};

ミドルウェアの最新のAPI変更にアップデートするには、移行ガイドを参照してください。

Vercelで無料でミドルウェアを試す、またはセルフホスティングの場合はnext startを使用してください。

オンデマンド増分静的再生 (安定版)

オンデマンド増分静的再生 (ISR) を使用すると、再デプロイせずにサイトのコンテンツを更新できます。これにより、ヘッドレスCMSまたはコマースプラットフォームでデータが変更された場合に、サイトをすぐに更新することが容易になります。これはコミュニティから最も要望の多かった機能の1つであり、安定版になったことを嬉しく思っています。

pages/api/revalidate.js
export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' });
  }
 
  try {
    await res.revalidate('/path-to-revalidate');
    return res.json({ revalidated: true });
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating');
  }
}

増分静的再生は、Next.jsビルドAPI (next build) をサポートするすべてのプロバイダーで機能します。Vercelにデプロイした場合、オンデマンド再検証は、ページをエッジにプッシュすると約300msでグローバルに伝播します。

詳細については、ドキュメントを参照するか、オンデマンド再検証の動作を確認するためにデモをご覧ください

エッジAPIルート (実験的)

Next.jsは、APIルートにもEdgeランタイムを使用できるようになりました。EdgeランタイムはNode.jsよりも軽量なランタイムであり、低レイテンシで高速な起動を実現します。さらに、Edge APIルートはサーバーからのストリーミングレスポンスをサポートします。

configでAPIルートのランタイムを設定し、nodejs(デフォルト)またはexperimental-edgeを指定できます。

pages/api/hello.js
import type { NextRequest } from 'next/server';
 
export default (req: NextRequest) => {
  return new Response(`Hello, from ${req.url} I'm now an Edge API Route!`);
};
 
export const config = {
  runtime: 'experimental-edge',
};

Edgeランタイムは軽量であるため、高速な起動に対応するために制限があります。たとえば、fsなどのNode.js固有のAPIはサポートされていません。したがって、APIルートのデフォルトランタイムはnodejsのままです。

詳細については、ドキュメントを参照してください。

エッジサーバーサイドレンダリング (実験的)

Next.jsは、サーバーサイドレンダリングにもEdgeランタイムを使用できるようになりました。

前述のように、EdgeランタイムはNode.jsよりも軽量なランタイムであり、低レイテンシで高速な起動を実現します。React 18と併用すると、ページのストリーミングサーバーサイドレンダリングが可能になります。

Next.jsは、サーバーサイドレンダリングページのデフォルトランタイムとしてNode.jsを使用します。12.2以降、React 18を使用している場合は、Edgeランタイムの使用を選択できます。

next.config.jsでグローバルにランタイムを設定し、nodejsまたはexperimental-edgeを指定できます。

next.config.js
module.exports = {
  experimental: {
    runtime: 'experimental-edge',
  },
};

デフォルトのページランタイムを変更すると、SSRストリーミングサーバーコンポーネントなどのすべてのページに影響します。このデフォルトは、runtime構成をエクスポートすることで、ページごとにオーバーライドすることもできます。

pages/index.js
export const config = {
  runtime: 'nodejs',
};
 
export default function Home() {}

実行時にprocess.env.NEXT_RUNTIME環境変数を確認し、webpackコンパイル時にoptions.nextRuntime変数を調べることで、使用しているランタイムを検出できます。

詳細については、ドキュメントを参照してください。

next/imageの改善点

next/future/imageコンポーネント (実験的)

現在のImageコンポーネントに関する皆様からのフィードバックを参考に、新しいnext/imageの早期プレビューを共有できることを嬉しく思います。この新しく改良されたイメージコンポーネントは、クライアント側のJavaScriptを削減し、画像のスタイル設定を簡素化します。

  • <div>または<span>ラッパーなしで単一の<img>をレンダリングします。
  • 標準のstyleプロパティのサポートを追加しました。
  • styleまたはclassNameに代えて、layoutobjectFitobjectPositionプロパティを削除しました。
  • ネイティブの遅延読み込みに代えて、IntersectionObserverの実装を削除しました。
  • loader構成をloaderプロパティに代えました。
  • 注: fillモードはまだないため、widthheightプロパティが必要です。

ネイティブのloading="lazy"はReactのハイドレーションとクライアント側のJavaScriptを待つ必要がないため、パフォーマンスが向上します。

詳細については、ドキュメントを参照してください。

リモートパターン (実験的)

next/imageは、組み込みのイメージ最適化APIを使用する場合に、リモートイメージのワイルドカードを指定できる実験的な構成オプションremotePatternsをサポートするようになりました。これにより、ドメイン名に対して正確な一致のみを行う既存のimages.domains構成を超えた、より強力なマッチングが可能になります。

next.config.js
module.exports = {
  experimental: {
    images: {
      remotePatterns: [
        {
          // The `src` property hostname must end with `.example.com`,
          // otherwise this will respond with 400 Bad Request.
          protocol: 'https',
          hostname: '**.example.com',
        },
      ],
    },
  },
};

詳細については、ドキュメントを参照してください。

イメージ最適化の無効化

ゼロコンフィグのイメージ最適化APIは、要求に応じてサーバーがオンデマンドでイメージを最適化する必要があるため、next exportの使用を妨げます。今日まで、next exportを対象とするユーザーは、サードパーティのイメージ最適化プロバイダーを使用するためにloaderを構成する必要がありましたが、利用可能なプロバイダーがない場合は明確な解決策がありませんでした。本日より、next exportユーザーは、新しい構成プロパティを使用して、すべてのnext/imageインスタンスのイメージ最適化を無効にできます。

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

SWCプラグイン (実験的)

Next.jsコンパイラは、JavaScriptコードの変換と圧縮にSWCを使用します。SWCはNext.js 12.0で導入され、ローカル開発とビルドのパフォーマンスの両方が向上しました。

コンパイル時のSWC変換動作をカスタマイズするために、(WebAssemblyで記述された)プラグインを追加できるようになりました。

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      ['css-variable/swc', { displayName: true, basePath: __dirname }],
    ],
  },
};

詳細については、ドキュメントを参照してください。

React 18サポートの改善

  • styled-componentsemotionなどのCSS-in-JSライブラリに対するサポートが向上し、よりスムーズなアップグレードエクスペリエンスを実現し、破壊的な変更はありません。
  • AMPとHTMLのポスト最適化(CSS、フォントの最適化)が適切にサポートされるようになりました。
  • next/headがReact 18をサポートするようになりました。
  • スクリーンリーダーやその他の支援技術にページ遷移を適切にアナウンスするために使用されるNext.jsのルートアナウンサーが、React 18をサポートするようになりました。

その他の改善点

  • Next.jsコンパイラにおけるEmotion変換のサポート。@emotion/babel-pluginのほとんどの機能がサポートされるようになり、importMapを使用していない限り、削除できます。詳細については、ドキュメントを参照してください
  • Next.jsコンパイラにおけるstyled-components変換のサポートが向上し、cssPropオプションを含むデフォルトオプションのカスタマイズが可能になりました。詳細については、ドキュメントを参照してください
  • JavaScript ESモジュールに対するサポートが向上したため、next/imagenext/linkなどのコンポーネントを正しくimportできるようになりました。
  • next/linkで子要素として<a>を手動で追加する必要がなくなりました。現在、後方互換性のある方法でこの動作を有効化できます
  • browsersListを変更することで、モダンなJavaScriptのみを配信するための実験的なサポートを追加しました。next.config.jsexperimentalオプションでbrowsersListForSwc: truelegacyBrowsers: falseを設定することで、この動作を有効化できます。
  • 新しい@swc/helpers最適化により、バンドル間の重複が防止され、最小構成では約2KB、より大きなアプリケーションではさらにバンドルサイズが削減されます。
  • Next.jsのインストールサイズを大幅に削減しました。これは、モノレポをpnpmに移行したことで、プリコンパイル済みバージョンを作成する際に重複パッケージを削除できるようになったためです。これにより、インストールサイズは14MB削減されました。
  • Next.jsのセルフホスティングの改善に向けた継続的な取り組みとして、実験的なoutputStandalone: true構成をoutput: 'standalone'に安定化しました。この構成により、必要なファイル/アセットのみを含めることで、構築されたデプロイパッケージにnode_modules全体をインストールする必要がなくなるなど、デプロイサイズが大幅に削減されます。この構成は、with-dockerの例で確認できます。

レイアウトRFCと高度なルーティングサポート

お見逃しのないよう、先月、レイアウトRFCを発表しました。これは、2016年の導入以来、Next.jsにとって最大のアップデートであり、以下を含みます。

  • ネストされたレイアウト: ネストされたルートを使用して複雑なアプリケーションを構築します。
  • サーバーコンポーネント向けに設計: サブツリーナビゲーション向けに最適化されています。
  • データフェッチの改善: ウォーターフォールを回避しながらレイアウトでフェッチします。
  • React 18機能の使用: ストリーミング、トランジション、サスペンス。
  • クライアントとサーバーのルーティング: SPAのような動作を持つサーバー中心のルーティング。
  • 100%増分採用可能: 破壊的な変更がないため、段階的に採用できます。
  • 高度なルーティング規則: オフスクリーンスタッシング、インスタントトランジションなど。

詳細については、RFCを参照するか、フィードバックを提供してください

コントリビューターの皆様、ありがとうございます

Next.jsは、**2,000人以上の個々の開発者**、Google ChromeやMetaなどの業界パートナー、そしてVercelのコアチームによる共同作業の成果です。

このリリースは、@huozhi、@ijjk、@kwonoj、@ViolanteCodes、@akrabdev、@timneutkens、@jpveilleux、@stigkj、@jgoping、@oof2win2、@Brooooooklyn、@CGamesPlay、@lfades、@molebox、@steven-tey、@SukkaW、@Kikobeats、@balazsorban44、@erikbrinkman、@therealmarzouq、@remcohaszing、@perkinsjr、@shuding、@hanneslund、@housseindjirdeh、@RobertKeyser、@styfle、@htunnicliff、@lukeshumard、@sagnik3、@pixelass、@JoshuaKGoldberg、@rishabhpoddar、@nguyenyou、@kdy1、@sidwebworks、@gnoff、@gaspar09、@feugy、@mfix-stripe、@javivelasco、@Chastrlove、@goncharov-vlad、@NaveenDA、@Firfi、@idkwhojamesis、@FLCN-16、@icyJoseph、@ElijahPepe、@elskwid、@irvile、@Munawwar、@ykolbin、@hulufei、@baruchadi、@imadatyatalah、@await-ovo、@menosprezzi、@gazs、@Exortions、@rubens-lopes、@woochul2、@stefee、@stmtk1、@jlarmstrongiv、@MaedahBatool、@jameshfisher、@fabienheureux、@TxHawks、@mattbrandlysonos、@iggyzap、@src200、@AkifumiSato、@hermanskurichin、@kamilogorek、@ben-xD、@dawsonbooth、@Josehower、@crutchcorn、@ericmatthys、@CharlesStover、@charlypoly、@apmatthews、@naingaungphyo、@alexandrutasica、@stefanprobst、@dc7290、@DilwoarH、@tommarshall、@stanhong、@leerob、@appsbytom、@sshyam-gupta、@saulloalmeida、@indicozy、@ArianHamdi、@Clariity、@sebastianbenz、@7iomka、@gr-qft、@Schniz、@dgagn、@sokra、@okbel、@tbvjaos510、@dmvjs、@PepijnSenders、@JohnPhamous、@kyliau、@eric-burel、@alabhyajindal、@jsjoeio、@vorcigernix、@clearlyTHUYDOAN、@splatterxl、@manovotny、@maxproske、@nvh95、@frankievalentine、@nuta、@bagpyp、@dfelsie、@qqpann、@atcastle、@jsimonrichard、@mass2527、@ekamkohli、@Yuddomack、@tonyspiro、@saurabhmehta1601、@banner4422、@falsepopsky、@jantimon、@henriqueholtz、@ilfa、@matteobruni、@ryscheng、@hoonoh、@ForsakenHarmony、@william-keller、@AleksaC、@Miikis、@zakiego、@radunemerenco、@AliYusuf95、そして@dominiksipowiczの皆様による貢献によって実現しました。