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

2020年7月27日月曜日

Next.js 9.5

投稿者

本日、Next.js 9.5 を発表できることを嬉しく思います。このバージョンには、次の機能が含まれています。

安定したインクリメンタル静的再生成

Next.js は 9.3 で 静的サイト生成メソッド を導入し、明確な目標がありました。それは、静的サイトの利点(常に高速、常にオンライン、グローバルにレプリケート)を、Next.js で知られている動的なデータに対する優れたサポートとともに得ることでした。

両方の利点を享受するために、Next.js はインクリメンタル静的生成を導入しました。これは、サイトをビルドした後で静的コンテンツを更新する機能です。getStaticPathsfallback: true オプションを使用することで、新しい静的ページを実行時に登録できます。

Next.js は、データセットのサイズに関係なく、この方法で無限の数のページをオンデマンドで静的に事前レンダリングできます。

本日、既存のページを更新するためのメカニズムであるインクリメンタル静的再生成一般提供を発表します。これは、トラフィックに応じてバックグラウンドでページを再レンダリングすることによって実現されます。

stale-while-revalidateに触発されたバックグラウンド再生成は、トラフィックが中断されることなく、常に静的ストレージから提供されることを保証し、新しくビルドされたページは生成が完了した後のみプッシュされます。

export async function getStaticProps() {
  return {
    props: await getDataFromCMS(),
    // we will attempt to re-generate the page:
    // - when a request comes in
    // - at most once every second
    revalidate: 1,
  };
}

revalidate フラグは、キャッシュスタンプを回避するために、1 回の生成が発生する秒数です。

従来の SSR とは異なり、インクリメンタル静的再生成は、静的サイトの利点を維持することを保証します。

  • レイテンシのスパイクなし。ページは一貫して高速に提供されます。
  • ページがオフラインになることはありません。バックグラウンドでのページ再生成が失敗した場合でも、古いページは変更されません。
  • データベースとバックエンドの負荷が低い。ページは最大でも同時に1回再計算されます。

ページを追加するインクリメンタル機能と、それらを遅延更新する機能、およびプレビューモードは、すべて安定しており、`next start` と Vercel エッジプラットフォーム の両方で、すぐに完全にサポートされます。

この新機能を示すために、特定のイシューのさまざまな GitHub リアクションのカウントを表示する静的ページを再生成する例を作成しました:https://reactions-demo.vercel.app/

After the first visit following our emoji reaction, a new page generation kicks off in the background. Every single request throughout is served from static cache.
絵文字リアクションの後、最初の訪問でバックグラウンドで新しいページ生成が開始されます。その間のすべてのリクエストは、静的キャッシュから提供されます。

次に、2 つの追加のインクリメンタル静的生成機能に対応する補足 RFC を作業する予定です。

  • 複数のページを一度に再生成および無効化する(ブログインデックスと特定のブログ投稿など)
  • イベント(CMS ウェブフックなど)をリッスンして、ユーザーのトラフィックの前に再生成する

詳細については、getStaticProps ドキュメントをご覧ください。

カスタマイズ可能なベースパス

Next.js プロジェクトは、常にドメインのルートから提供されるわけではありません。たとえば、`/docs` のようなサブパスで Next.js プロジェクトをホストしたい場合があります。これにより、Next.js プロジェクトがドメインのそのセクションのみをカバーするようになります。

これまでは可能でしたが、かなりの追加設定が必要でした。たとえば、すべての `` にプレフィックスを追加したり、Next.js が正しいパスから JavaScript バンドルを提供していることを確認したりする必要があります。

この問題に対処するため、新しい構成オプションを導入しました。`basePath` を使用すると、Next.js プロジェクトをドメインのサブパスで簡単にホストできます。

`basePath` の使用を開始するには、`next.config.js` に追加できます。

next.config.js
module.exports = {
  basePath: '/docs',
};

`basePath` を構成した後、プロジェクトは提供されたパス(この場合は `/docs`)から自動的にルーティングされます。

`next/link` または `next/router` を使用してプロジェクト内の他のページにリンクする場合、`basePath` が自動的にプレフィックスされます。これにより、プロジェクトを変更せずに `basePath` を変更できます。

例として、`next/link` を使用して別のページにルーティングする場合を挙げます。

import Link from 'next/link';
 
export default function HomePage() {
  return (
    <>
      <Link href="/documentation-page">
        <a>Documentation page</a>
      </Link>
    </>
  );
}

このように `next/link` を使用すると、次の HTML が Web ブラウザにレンダリングされます。

<a href="/docs/documentation-page">Documentation page</a>

詳細については、`basePath` ドキュメントをご覧ください。

リライト、リダイレクト、ヘッダーのサポート

リライト

Next.js プロジェクトをビルドする際、特定のルートを別の URL にプロキシしたい場合があります。たとえば、スタックに Next.js を段階的に導入したい場合、Next.js プロジェクトに存在するページにルーティングし、一致しなかったすべてを移行元の古いプロジェクトにルーティングしたいとします。

Next.js 9.5 では、`rewrites` という新しい構成オプションを導入しました。これにより、受信したリクエストパスを外部 URL を含む別の宛先パスにマッピングできます。

たとえば、特定のルートを `example.com` に書き換えたい場合があります。

next.config.js
module.exports = {
  async rewrites() {
    return [
      { source: '/backend/:path*', destination: 'https://example.com/:path*' },
    ];
  },
};

この場合、`/backend` 以下のすべてのパスは `example.com` にルーティングされます。

Next.js プロジェクトのルートが一致したかどうかを確認し、一致しなかった場合は前のプロジェクトに書き戻すこともできます。これは、Next.js の段階的な導入に非常に役立ちます。

module.exports = {
  async rewrites() {
    return [
      // check if Next.js project routes match before we attempt proxying
      {
        source: '/:path*',
        destination: '/:path*',
      },
      {
        source: '/:path*',
        destination: `https://example.com/:path*`,
      },
    ];
  },
};

この場合、まずすべてのパスに一致します。一致しない場合は `example.com`(前のプロジェクト)にプロキシされます。

`rewrites` 機能の詳細については、rewrites ドキュメントをご覧ください。

リダイレクト

ほとんどのウェブサイトには、少なくともいくつかのリダイレクトが必要です。特にプロジェクトルートの構造を変更する場合。たとえば、`/blog` を `/news` に移動する場合など。

以前は、Next.js プロジェクトでリダイレクトリストを管理するには、カスタムサーバーまたはカスタム `_error` ページを設定して、ルートのリダイレクトが設定されているかを確認する必要がありました。しかし、これには、静的およびサーバーレス最適化の重要な要素(サーバーを持つことによる)が無効になるか、十分な人間工学が得られないという犠牲が伴いました。

Next.js 9.5 から、`next.config.js` の `redirects` キーの下にリダイレクトリストを作成できるようになりました。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ];
  },
};

`redirects` 機能の詳細については、redirects ドキュメントをご覧ください。

ヘッダー

Next.js では、静的生成とサーバーサイドレンダリングの両方を使用するハイブリッドプロジェクトを構築できます。サーバーサイドレンダリングでは、受信リクエストにヘッダーを設定できます。静的ページでは、これまでヘッダーの設定はできませんでした。

すべての Next.js ルートに適用される `headers` プロパティを `next.config.js` に導入しました。

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Feature-Policy',
            // Disable microphone and geolocation
            value: "microphone 'none'; geolocation 'none'",
          },
        ],
      },
    ];
  },
};

`headers` オプションを使用すると、`Feature-Policy` や `Content-Security-Policy のような一般的なヘッダーを設定できます。

`headers` 機能の詳細については、headers ドキュメントをご覧ください。

URL におけるオプションの末尾スラッシュ

Next.js が 3 年前に導入されたとき、末尾スラッシュのあるすべての URL は常に 404 ページを返すのがデフォルトの動作でした。

効果的でしたが、一部のユーザーは、この動作を変更する機能の提供を求めていました。たとえば、以前は常に末尾スラッシュが強制されていた既存のプロジェクトを Next.js に移行する場合などです。

Next.js 9.5 では、`next.config.js` に `trailingSlash` という新しいオプションを導入しました。

この新しいオプションにより、Next.js が末尾スラッシュの動作を自動的に処理するようになります。

  • 末尾スラッシュのある URL を末尾スラッシュのない URL に自動的にリダイレクトします。例:`/about/` から `/about` へ。
  • `trailingSlash` が `true` に設定されている場合、末尾スラッシュのない URL は末尾スラッシュのある URL にリダイレクトされます。例:`/about` から `/about/` へ。
  • `next/link` が末尾スラッシュを自動的に適用/削除し、不要なリダイレクトを回避するようにします。
next.config.js
module.exports = {
  // Force a trailing slash, the default value is no trailing slash (false)
  trailingSlash: true,
};

`trailingSlash` 機能の詳細については、trailingSlash ドキュメントをご覧ください。

ページバンドル向けの永続キャッシュ

Next.js ページを作成する際、すべてのスクリプトバンドル、CSS スタイルシート、および HTML の作成は完全に自動化されており、ユーザーから隠されています。Next.js 9.5 より前の生成された `