➡️

Next.js 13 和訳

2022/10/26に公開

https://nextjs.org/blog/next-13

雑に翻訳しました。
意訳がめちゃくちゃ含まれているので注意です。


  • app/ Directory (beta): より簡単に、より速く、クライアント側JSのサイズをより小さく。
    • Layouts
    • React Server Components
    • Streaming
  • Turbopack (alpha): Rustで実装したWebpackの代替バンドラーで最大700倍高速化。
  • New next/image (stable): ネイティブブラウザの遅延ロードを利用し、より高速に。
  • New @next/font (beta): レイアウトシフトをゼロにする自動セルフホストフォント。
  • Improved next/link: APIを簡素化し、<a>タグを自動的に表示するようにしました。

次のコマンドを利用して更新出来ます。

npm i next@latest react@latest react-dom@latest eslint-config-next@latest

app/ Directory (beta)

Next.jsで最も愛されている機能のひとつに、ファイルシステムベースのルーターがあります。フォルダ内にファイルを配置すると、アプリケーション内に即座にルートを作成することができます。設定は不要です。

本日、Next.jsのルーティングとレイアウトを改善し、app/ディレクトリ (beta)を導入しました。
これは、以前に公開したLayouts RFCに対するコミュニティからのフィードバックを反映しています。
これには、以下のサポートが含まれます。

  • Layouts: 状態を維持したままUIを簡単に共有し、再レンダリングを回避することができます。
  • Server Components: 動的なアプリケーションのためにサーバーファーストをデフォルトにする。
  • Streaming: ロード状態を瞬時に表示し、アップデートをストリームで表示します。
  • Suspense for Data Fetching: 新しいusehookは、コンポーネントレベルのフェッチを可能にします。

app/ディレクトリは、既存のpagesディレクトリと共存して、段階的に採用することができます。Next.js 13へのアップグレードではapp/ディレクトリを使う必要はありませんが、より小さなJavaScriptを配信しながら複雑なインターフェイスを構築するための基盤を構築する事が出来ます。


app/ディレクトリは、既存のpages/ディレクトリから段階的に採用することができます。


Layouts

app/ディレクトリを使用すると、ナビゲーションをまたいで状態を維持し、高価な再レンダリングを回避し、高度なルーティングパターンを可能にする複雑なインターフェースを簡単に作成することができます。さらに、コンポーネント、テスト、スタイルなど、アプリケーションのコードをルーティングと一緒に配置することもできます

app/内にルートを作成するには、page.jsという1つのファイルが必要です。

app/page.js
// このファイルは、インデックスルート(/)にマッピングされます。
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

また、ファイルシステムを通じてレイアウトを定義することができるようになりました。レイアウトは、複数のページ間で UI を共有します。ナビゲーション時に、レイアウトは状態を保持し、インタラクティブな状態を維持し、再レンダリングは行いません。

app/blog/layout.js
export default function BlogLayout({ children }) {
  return <section>{children}</section>;
}

レイアウトとページについて詳しくはこちらサンプルのデプロイはこちらで試せます。


Server Components

app/ディレクトリは、Reactの新しいServer Componentsアーキテクチャのサポートを導入しています。Server Componentsは、サーバとクライアントでそれぞれ得意な用途に使い分ける事で、高速で高度にインタラクティブなアプリを単一のプログラミングモデルで構築でき、素晴らしい開発体験を提供します。

また、Server Componentsを使用することで、クライアントに送信されるJavaScriptの量を減らし、最初のページロードを高速化することができます

ルートが読み込まれると、キャッシュ可能でサイズも予測可能なNext.jsとReactのランタイムが読み込まれます。このランタイムは、アプリケーションが大きくなってもサイズが大きくなることはありません。さらに、ランタイムは非同期にロードされるので、サーバーにあるHTMLをクライアントで徐々に拡張していくことができます。

サーバーコンポーネントについて詳しくはこちらサンプルのデプロイはこちらで試せます。


Streaming

app/ディレクトリは、UIのレンダリングを段階的に行い、レンダリングされた単位でクライアントに段階的にストリーミングする機能を導入しています。

Server ComponentsとNext.jsのネストされたレイアウトを使用すると、特にデータを必要としないページの部分を即座にレンダリングし、データを取得しているページの部分についてはロード状態を表示することができます。この方法により、ユーザーはページ全体がロードされるのを待たずに、ページとのやりとりを開始することができます。


app/ディレクトリは、React Suspenseを使用した専用のloading.jsファイルによって Instant Loading UI をサポートします。

Vercelにデプロイすると、app/ディレクトリを使用する Next.js 13アプリケーションは、パフォーマンスを向上させるためにNode.jsとEdgeの両方のランタイムでデフォルトでレスポンスをストリームするようになります。

ストリーミングについて詳しくはこちらサンプルのデプロイはこちらで試せます。


Data Fetching

app/ディレクトリは、React Suspense上に構築されており、データをフェッチする強力な新しい方法を導入しています。この新しいusehookは、getStaticPropsやgetServerSidePropsといったこれまでのNext.js APIを置き換え、Reactの未来に寄り添うようなものになっています。

app/page.js
import { use } from 'react';

async function getData() {
  const res = await fetch('...');
  const name: string = await res.json();
  return name;
}

export default function Page() {
  // この値は完全に型付けされます
  // 戻り値はシリアライズされません。
  // Date、Map、Setなどを返すことができます。
  const name = use(getData());

  return '...';
}

コンポーネントレベルでデータをフェッチ、キャッシュ、再バリデートする柔軟な方法が1つ増えました。これは、静的サイト生成(SSG)、サーバーサイドレンダリング(SSR)、インクリメンタル静的再生(ISR)のすべての利点が、ReactのusehookとWebfetchAPIを拡張することで利用可能になったことを意味します。

// このリクエストは手動で無効化されるまでキャッシュされる必要があります。
// `getStaticProps`に似ています。
// `force-cache`がデフォルトです。省略することもできます。
fetch(URL, { cache: 'force-cache' });

// このリクエストは、すべてのリクエストでリフェッチされる必要があります。
// `getServerSideProps`に似ています。
fetch(URL, { cache: 'no-store' });

// このリクエストは、10秒間の有効期限でキャッシュされる必要があります。
// `getStaticProps`に`revalidate`オプションをつけたものに似ています。
fetch(URL, { next: { revalidate: 10 } });

app/ディレクトリでは、レイアウト、ページ、コンポーネント内のデータを取得することができ、サーバーからのストリーミングレスポンスもサポートされています。

リッチでインタラクティブなクライアントサイドのエクスペリエンスを維持しながら、デフォルトで配信されるJavaScriptのサイズを大幅に減らすことができます。アプリケーションのServer Componentsの数が増えても、必要なクライアント側のJavaScriptのサイズは一定です

app/ディレクトリでは、ローディングとエラー状態を処理する人間工学的な方法と、レンダリング時のUIのストリームを可能にしています。将来のリリースでは、データミューテーションの改善と簡素化も行う予定です。


app/ディレクトリで、新たに専用のloading.jsファイルを使用することで、Suspension境界のあるInstant Loading UIを自動で作成することができます。

私たちは、オープンソースコミュニティ、パッケージメンテナ、およびReactエコシステムに貢献している他の企業とともに、ReactとNext.jsのこの新しい時代のために構築することに興奮しています。データ取得をコンポーネント内に配置する機能と、クライアントへのJavaScriptの配布を減らす機能は、コミュニティのフィードバックで重要な2つの部分であり、私たちはapp/ディレクトリを追加することに興奮しています。

データフェッチについて詳しくはこちら、サンプルのデプロイはこちらで試せます。


ターボパックの紹介 (alpha)

Next.js 13には、Webpackの後継となるRustベースの新しいTurbopackが含まれています。

Webpackは30億回以上ダウンロードされています。Webを構築する上で不可欠な要素である一方で、私たちはJavaScriptベースのツールで可能な最大のパフォーマンスの限界に達しました。

Next.js 12では、Rustを使ったネイティブなツールへの移行を開始しました。まずBabelから移行し、17倍高速なトランスパレーションを実現しました。次にTerserを置き換え、6倍高速な圧縮を実現しました。今こそ、バンドルにネイティブを取り入れる時です。

Next.js 13 で Turbopack alpha を使用すると、次のようになります。

  • Webpackより700倍高速なアップデート。
  • Viteより10倍高速なアップデート。
  • Webpackより4倍高速なコールドスタート。


Turbopackは、Webpackの後継となるRustベースのアプリケーションで、大規模なアプリケーションのHMRを700倍高速化します。

Turbopackは、開発時に必要な最低限のアセットのみをバンドルしているため、起動時間が非常に速いのが特徴です。3,000個のモジュールを使用したアプリケーションの場合、Turbopackの起動時間は1.8秒です。Viteは11.4秒、Webpackは16.5秒です。

Turbopackは、Server Components、TypeScript、JSX、CSS などに、すぐに対応できます。アルファ版では、まだ多くの機能がサポートされていません。ローカルのイテレーションを高速化するために、Turbopack を使用した感想をお待ちしています。

今日、Next.js 13でnext dev --turboを使って、Turbopack alpha を試してみてください。


next/image

Next.js 13では、強力な新しいImageコンポーネントが導入され、レイアウトシフトなしで簡単に画像を表示したり、オンデマンドでファイルを最適化し、パフォーマンスを向上させることができます。

Next.js Community投票では、70%の回答者がNext.js Imageコンポーネントをプロダクションで使用し、Core Web Vitalsが改善されたと答えています。Next.js 13では、next/imageをさらに改良しています。

新しいImageコンポーネントの内容です。

  • クライアントサイドのJavaScriptを削減
  • スタイルと設定がより簡単になりました。
  • デフォルトでaltタグを必要とし、アクセシビリティを高めました。
  • ウェブプラットフォームとの整合性向上
  • ブラウザネイティブの遅延ロードによりハイドレーションが不要なため、より高速になります。
import Image from 'next/image';
import avatar from './lee.png';

function Home() {
  // アクセシビリティの向上のため、"alt "を必須としました。
  // optional: 画像ファイルはapp/ディレクトリ内に配置可能です。
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

Imageコンポーネントの詳細はこちらサンプルのデプロイはこちらで試せます。


next/imageをNext.js 13にアップグレードする

古いImageコンポーネントは、next/legacy/imageに名前が変更されました。私たちは、next/imageの既存の使用法をnext/legacy/imageに自動的に更新するcodemodを提供しています。例えば、このコマンドをルートから実行すると、あなたの./pagesディレクトリでcodemodが実行されます。

npx @next/codemod next-image-to-legacy-image ./pages

codemodについて詳しくはこちらドキュメントはこちらをチェックしてください


@next/font

Next.js 13では、全く新しいフォントシステムを導入しています。

  • カスタムフォントを含む、フォントの自動最適化
  • 外部ネットワークへのリクエストを削除し、プライバシーとパフォーマンスを改善
  • あらゆるフォントファイルに対する自動セルフホスティング機能を内蔵。
  • CSSのサイズ調整プロパティを使用して、レイアウトシフトを自動的にゼロにします。

この新しいフォントシステムにより、パフォーマンスとプライバシーを考慮した上で、すべてのGoogle Fontsを便利に使用することができます。CSSとフォントのファイルはビルド時にダウンロードされ、残りの静的アセットと一緒にセルフホスティングされます。ブラウザからGoogleにリクエストが送信されることはありません

import { Inter } from '@next/font/google';

const inter = Inter();

<html className={inter.className}>

また、カスタムフォントにも対応しており、フォントファイルの自動セルフホスティング、キャッシュ、プリロードに対応しています。

import localFont from '@next/font/local';

const myFont = localFont({ src: './my-font.woff2' });

<html className={myFont.className}>

フォント表示、プリロード、フォールバックなど、優れたパフォーマンスとレイアウトのずれを防ぎつつ、フォント読み込みのあらゆる部分をカスタマイズすることができます。

新しいFontコンポーネントの詳細はこちらサンプルのデプロイはこちらで試せます


next/link

next/linkで、<a>タグを手動で追加する必要がなくなりました。

これは12.2で実験的なオプションとして追加されたもので、現在はデフォルトになっています。Next.js 13では、<Link>は常に<a>タグを表示し、その下にあるタグにpropを転送することができます。たとえば

import Link from 'next/link'

// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a>About</a>
</Link>

// Next.js 13: `<Link>` always renders `<a>`
<Link href="/about">
  About
</Link>

改良されたLinkコンポーネントの詳細はこちらサンプルのデプロイはこちらで試せます


next/linkをNext.js 13にアップグレードする

あなたのLinkコンポーネントをNext.js 13にアップグレードするために、コードベースを自動的に更新するcodemodを提供しています。たとえば、このコマンドをルートから実行すると、あなたの ./pages ディレクトリで codemod が実行されます。

npx @next/codemod new-link ./pages

codemodについて詳しくはこちらドキュメントはこちらをチェックしてください


OG画像生成

ソーシャルカードは、オープングラフ画像とも呼ばれ、コンテンツのクリックによるエンゲージメント率を大幅に向上させることができ、最大40%のコンバージョン率向上を示した実験結果もあります。

静的なソーシャルカードは、時間がかかり、エラーが発生しやすく、維持するのが困難です。そのため、ソーシャルカードはしばしば省略されることがあります。これまで、パーソナライズされ、その場で計算される必要がある動的なソーシャルカードは、困難で高価でした。

Next.jsとシームレスに連携し、ダイナミックなソーシャルカードを生成する新しいライブラリ@vercel/ogを作成しました。

pages/api/og.jsx
import { ImageResponse } from '@vercel/og';

export const config = {
  runtime: 'experimental-edge',
};

export default function () {
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
        }}
      >
        Hello, World!
      </div>
    ),
  );
}

このアプローチは、Vercel Edge Functions、WebAssembly、およびHTMLとCSSを画像に変換するための全く新しいコアライブラリを使用し、Reactコンポーネントの抽象化を活用することにより、既存のソリューションよりも5倍高速化されています。

OG画像生成の詳細はこちらサンプルのデプロイはこちらで試せます


Middleware API Updates

Next.js 12では、Next.jsのルーターで完全な柔軟性を実現するために、ミドルウェアを導入しました。最初のAPI設計に対するみなさんのフィードバックを聞き、開発者のエクスペリエンスを向上させ、強力な新機能を追加するために、いくつかの追加を行いました。

リクエスト時にヘッダーをより簡単に設定できるようになりました。

middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // リクエストヘッダを複製して、新しいヘッダ`x-version`をセットします
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13');

  // NextResponse.rewriteにリクエストヘッダを設定することもできます
  const response = NextResponse.next({
    request: {
      // New request headers
      headers: requestHeaders,
    },
  });

  // 新しいレスポンスヘッダー`x-version`を設定する
  response.headers.set('x-version', '13');
  return response;
}

また、書き換えリダイレクトを行わず、Middlewareから直接レスポンスを提供できるようになりました。

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';

// ミドルウェアを `/api/` で始まるパスに限定する。
export const config = {
  matcher: '/api/:function*',
};

export function middleware(request: NextRequest) {
  // 認証関数を呼び出し、リクエストを確認する
  if (!isAuthenticated(request)) {
    // エラーメッセージを示すJSONで応答する
    return NextResponse.json(
      {
        success: false,
        message: 'Auth failed',
      },
      {
        status: 401,
      },
    );
  }
}

Middlewareからのレスポンス送信には、現在、next.config.js内のexperimental.allowMiddlewareResponseBodyという設定オプションが必要です。


破壊的変更

  • Reactの最小バージョンは17.0.2から18.2.0に引き上げられました。
  • Node.jsの最小バージョンは12.22.0から14.0.0に変更されました。12.xが耐用年数に達したため (PR)。
  • swcMinifyの設定プロパティがfalseからtrueに変更されました。詳細は Next.js Compilerを参照してください。
  • next/imagenext/legacy/imageに名称変更されました。next/future/imagenext/imageに名称変更されました。インポートの名前を安全かつ自動的に変更するためのcodemodが用意されています
  • next/linkの子に<a>タグが必要でなくなりました。legacyBehaviorプロパティを追加して従来の挙動を使用するか、<a>タグを削除してアップグレードしてください。自動的にアップグレードするためのcodemodが用意されています
  • User-Agentがボットの場合、ルートがプリフェッチされないようになりました。
  • next.config.jsの非推奨のtargetオプションは削除されました。
  • 対応ブラウザは、Internet Explorerを外し、モダンブラウザを対象とするように変更されました。Browserslistを使用して対象ブラウザを変更することは可能です。
    • Chrome 64+
    • Edge 79+
    • Firefox 67+
    • Opera 51+
    • Safari 12+

詳しくは、アップグレードガイドをご覧ください。


Community

6年前、私たちはNext.jsを一般に公開しました。私たちは、開発者の体験をシンプルにするゼロコンフィギュレーションのReactフレームワークを構築することを目指しました。振り返ってみると、コミュニティがどのように成長し、どのようなものを一緒に出荷できるようになったかを見るのは、信じられないことです。これからも続けていきましょう。

Next.jsは、2,400人以上の個人開発者、GoogleやMetaなどの業界パートナー、そして私たちのコアチームによる共同作業の結果です。Next.jsは、週に300万回以上のnpmダウンロードと94,000のGitHubスターを持ち、Web構築の最も人気のある方法の一つとなっています。

このリリースは、以下の方々の貢献によってもたらされました。
@ijjk, @huozhi, @HaNdTriX, @iKethavel, @timneutkens, @shuding, @rishabhpoddar, @hanneslund, @balazsorban44, @anthonyshew, @TomerAberbach, @philippbosch, @styfle, @mauriciomutte, @hayitsdavid, @abdennor, @Kikobeats, @cjdunteman, @Mr-Afonso, @kdy1, @jaril, @abdallah-nour, @North15, @feedthejim, @brunocrosier, @Schniz, @sedlukha, @hashlash, @Ethan-Arrowood, @fireairforce, @migueloller, @leerob, @janicklas-ralph, @Trystanr, @atilafassina, @nramkissoon, @kasperadk, @valcosmos, @henriqueholtz, @nip10, @jesstelford, @lorensr, @AviAvinav, @SukkaW, @jaycedotbin, @saurabhburade, @notrab, @kwonoj, @sanruiz, @angeloashmore, @falsepopsky, @fmontes, @Gebov, @UltiRequiem, @p13lgst, @Simek, @mrkldshv, @thomasballinger, @kyliau, @AdarshKonchady, @endymion1818, @pedro757, @perkinsjr, @gnoff, @jridgewell, @silvioprog, @mabels, @nialexsan, @feugy, @jackromo888, @crazyurus, @EarlGeorge, @MariaSolOs, @lforst, @maximbaz, @maxam2017, @teobler, @Nutlope, @sunwoo0706, @WestonThayer, @Brooooooklyn, @Nsttt, @charlypoly, @aprendendofelipe, @sviridoff, @jackton1, @nuta, @Rpaudel379, @marcialca, @MarDi66, @ismaelrumzan, @javivelasco, @eltociear, and @hiro0218.

Discussion