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

2022年6月28日火曜日

Next.js 12.2

投稿者

12.2でNext.jsの未来の基盤を構築しています

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

ミドルウェア (安定版)

12.2 ではミドルウェアが安定版となり、ユーザーからのフィードバックに基づいたAPIが改善されました。

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

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にデプロイすると、ページをエッジにプッシュする際にオンデマンド再検証が約300ミリ秒でグローバルに伝播します。

詳細については、ドキュメントを確認するか、デモを表示してオンデマンド再検証がどのように機能するかをご覧ください。

Edge API Routes (実験的)

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

API Route のランタイムは、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 Server-Rendering (実験的)

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 ストリーミングServer Componentsの機能を含むすべてのページに影響します。また、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プロップのサポートを追加しました。
  • layoutobjectFitobjectPositionプロップは、styleまたはclassNameに置き換えられました。
  • IntersectionObserverの実装を削除し、ネイティブの遅延読み込みに置き換えました。
  • loader設定は、loaderプロップに置き換えられました。
  • 注意: まだfillモードはないため、widthheightプロップは必須です。

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

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

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

next/image は、組み込みの Image Optimization 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 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で確認できます。

Layouts RFC & Advanced Routing Support

もし見逃していたら、先月発表されたLayouts RFCをご覧ください。これはNext.jsが2016年に導入されて以来最大のアップデートであり、以下が含まれます。

  • ネストされたレイアウト: 複雑なアプリケーションをネストされたルートで構築。
  • Server Components 向けに設計: サブツリーナビゲーションに最適化。
  • データ取得の改善: レイアウトでウォーターフォールを回避しながらデータを取得。
  • React 18 の機能を使用: ストリーミング、Transitions、Suspense。
  • クライアントおよびサーバー ルーティング: サーバー中心のルーティングと 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の貢献により実現しました。