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

2022年6月28日 火曜日

Next.js 12.2

投稿者

Next.js 12.2 で Next.js の未来の基盤を築きます

npm i next@latest を実行して今すぐ更新してください。

ミドルウェア (安定版)

Middleware が 12.2 で安定版になり、ユーザーからのフィードバックに基づいて API が改善されたことを発表できることを嬉しく思います。

Middleware を使用すると、リクエストが完了する前にコードを実行できます。受信したリクエストに基づいて、書き換え、リダイレクト、ヘッダーの追加、または 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: '/',
};

Middleware の最新の API 変更に更新するには、マイグレーションガイド を参照してください。

Vercel で Middleware を無料で試す、または 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でグローバルに伝播します。

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

Edge API ルート (実験版)

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

API ルートのランタイムは config で設定でき、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 Runtime は軽量であるため、高速起動に対応するための制限があります。例えば、fs のような Node.js 固有の API はサポートしていません。そのため、API Routes のデフォルトのランタイムは引き続き nodejs です。

詳細については、ドキュメントを確認してください

Edge サーバーレンダリング (実験版)

Next.js は、サーバーレンダリングに Edge Runtime を使用するようになりました。

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

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

ランタイムは 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 プロパティのサポートを追加しました。
  • layoutobjectFit、および objectPosition プロパティを削除し、style または className を優先しました。
  • ネイティブの遅延読み込み を優先し、IntersectionObserver の実装を削除しました。
  • loader 設定を削除し、loader プロパティを優先しました。
  • 注意: fill モードは (まだ) ないため、width および height プロパティは必須です。

これにより、ネイティブの 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 Compiler は、プロダクション向けに 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 Compiler での Emotion 変換のサポート。@emotion/babel-plugin のほとんどの機能がサポートされ、importMap を使用しない限り、削除できます。詳細については、ドキュメントを確認してください
  • Next.js Compiler での styled-components 変換のサポートを改善し、cssProp オプションを含むデフォルトオプションのカスタマイズを可能にしました。詳細については、ドキュメントを確認してください
  • JavaScript ES Modules のサポートが向上し、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 & 高度なルーティングサポート

ご存知ないかもしれませんが、先月、Next.js が 2016 年に導入されて以来最大のアップデートである Layouts RFC を発表しました。これには以下が含まれます。

  • ネストされたレイアウト: ネストされたルートを持つ複雑なアプリケーションを構築。
  • サーバーコンポーネント向けに設計: サブツリーナビゲーションに最適化。
  • データフェッチの改善: ウォーターフォールを回避しながらレイアウト内でフェッチ。
  • 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, and @dominiksipowicz.