Menu

experimental.adapterPath

Next.jsは、ビルドプロセスにフックするカスタムアダプターを作成できる実験的なAPIを提供します。これは、Next.jsの設定を変更したり、ビルド出力を処理したりする必要があるデプロイメントプラットフォームやカスタムビルド統合に役立ちます。

設定

アダプターを使用するには、experimental.adapterPathにアダプターモジュールへのパスを指定します:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    adapterPath: require.resolve('./my-adapter.js'),
  },
}
 
module.exports = nextConfig

アダプターの作成

アダプターは、NextAdapterインターフェースを実装するオブジェクトをエクスポートするモジュールです:

export interface NextAdapter {
  name: string
  modifyConfig?: (
    config: NextConfigComplete,
    ctx: {
      phase: PHASE_TYPE
    }
  ) => Promise<NextConfigComplete> | NextConfigComplete
  onBuildComplete?: (ctx: {
    routes: {
      headers: Array<ManifestHeaderRoute>
      redirects: Array<ManifestRedirectRoute>
      rewrites: {
        beforeFiles: Array<ManifestRewriteRoute>
        afterFiles: Array<ManifestRewriteRoute>
        fallback: Array<ManifestRewriteRoute>
      }
      dynamicRoutes: ReadonlyArray<ManifestRoute>
    }
    outputs: AdapterOutputs
    projectDir: string
    repoRoot: string
    distDir: string
    config: NextConfigComplete
    nextVersion: string
  }) => Promise<void> | void
}

基本的なアダプター構造

最小限のアダプター例を示します:

my-adapter.js
/** @type {import('next').NextAdapter} */
const adapter = {
  name: 'my-custom-adapter',
 
  async modifyConfig(config, { phase }) {
    // ビルドフェーズに基づいてNext.jsの設定を変更します
    if (phase === 'phase-production-build') {
      return {
        ...config,
        // 変更を追加してください
      }
    }
    return config
  },
 
  async onBuildComplete({
    routes,
    outputs,
    projectDir,
    repoRoot,
    distDir,
    config,
    nextVersion,
  }) {
    // ビルド出力を処理します
    console.log('Build completed with', outputs.pages.length, 'pages')
 
    // 異なる出力タイプにアクセスします
    for (const page of outputs.pages) {
      console.log('Page:', page.pathname, 'at', page.filePath)
    }
 
    for (const apiRoute of outputs.pagesApi) {
      console.log('API Route:', apiRoute.pathname, 'at', apiRoute.filePath)
    }
 
    for (const appPage of outputs.appPages) {
      console.log('App Page:', appPage.pathname, 'at', appPage.filePath)
    }
 
    for (const prerender of outputs.prerenders) {
      console.log('Prerendered:', prerender.pathname)
    }
  },
}
 
module.exports = adapter

APIリファレンス

modifyConfig(config, context)

next.configを読み込むすべてのCLIコマンド用に呼び出され、設定の変更が可能です。

パラメータ:

  • config:完全なNext.js設定オブジェクト
  • context.phase:現在のビルドフェーズ(phasesを参照)

**戻り値:**変更された設定オブジェクト(非同期になる場合があります)

onBuildComplete(context)

ビルドプロセスが完了した後に呼び出され、ルートと出力に関する詳細情報が提供されます。

パラメータ:

  • routes:ヘッダー、リダイレクト、リライト、動的ルートのルートマニフェストを含むオブジェクト
    • routes.headerssourcesourceRegexheadershasmissing、およびオプションのpriorityフィールドを持つヘッダールートオブジェクトの配列
    • routes.redirectssourcesourceRegexdestinationstatusCodehasmissing、およびオプションのpriorityフィールドを持つリダイレクトルートオブジェクトの配列
    • routes.rewritesbeforeFilesafterFilesfallback配列を持つオブジェクト。各配列にはsourcesourceRegexdestinationhasmissingフィールドを持つリライトルートオブジェクトが含まれます
    • routes.dynamicRoutessourcesourceRegexdestinationhasmissingフィールドを持つ動的ルートオブジェクトの配列
  • outputs:すべてのビルド出力に関する詳細情報をタイプ別に編成したもの
  • projectDir:Next.jsプロジェクトディレクトリへの絶対パス
  • repoRoot:検出されたリポジトリルートへの絶対パス
  • distDir:ビルド出力ディレクトリへの絶対パス
  • config:最終的なNext.js設定(modifyConfigが適用された状態)
  • nextVersion:使用されているNext.jsのバージョン
  • buildId:現在のビルドの一意の識別子

出力タイプ

outputsオブジェクトには、異なる出力タイプの配列が含まれます:

ページ(outputs.pages

pages/ディレクトリのReactページ:

{
  type: 'PAGES'
  id: string           // ルート識別子
  filePath: string     // ビルドされたファイルへのパス
  pathname: string     // URLパス名
  sourcePage: string   // pages/ディレクトリ内の元のソースファイルパス
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>  // トレースされた依存関係(キー:リポジトリルートからの相対パス、値:絶対パス)
  wasmAssets?: Record<string, string>  // バンドルされたwasmファイル(キー:名前、値:絶対パス)
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>  // 環境変数(edgeランタイムのみ)
  }
}

APIルート(outputs.pagesApi

pages/api/のAPIルート:

{
  type: 'PAGES_API'
  id: string
  filePath: string
  pathname: string
  sourcePage: string   // 元の相対ソースファイルパス
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
  }
}

Appページ(outputs.appPages

app/ディレクトリのpage.{js,ts,jsx,tsx}を含むReactページ:

{
  type: 'APP_PAGE'
  id: string
  filePath: string
  pathname: string     // RSCルートの場合は.rscサフィックスを含む
  sourcePage: string   // 元の相対ソースファイルパス
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
  }
}

Appルート(outputs.appRoutes

app/route.{js,ts,jsx,tsx}を含むAPIおよびメタデータルート:

{
  type: 'APP_ROUTE'
  id: string
  filePath: string
  pathname: string
  sourcePage: string
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
  }
}

プリレンダー(outputs.prerenders

ISR対応ルートと静的プリレンダー:

{
  type: 'PRERENDER'
  id: string
  pathname: string
  parentOutputId: string  // ソースページ/ルートのID
  groupId: number        // リバリデーショングループ識別子(同じgroupIdのプリレンダーは一緒にリバリデートされる)
  pprChain?: {
    headers: Record<string, string>  // PPRチェーンヘッダー(例:'x-nextjs-resume': '1')
  }
  parentFallbackMode?: 'blocking' | false | null  // getStaticPathsからのフォールバックモード
  fallback?: {
    filePath: string
    initialStatus?: number
    initialHeaders?: Record<string, string | string[]>
    initialExpiration?: number
    initialRevalidate?: number
    postponedState?: string  // PPR保留状態
  }
  config: {
    allowQuery?: string[]     // 許可されたクエリパラメータ
    allowHeader?: string[]    // ISRで許可されたヘッダー
    bypassFor?: RouteHas[]    // キャッシュバイパス条件
    renderingMode?: RenderingMode
    bypassToken?: string
  }
}

静的ファイル(outputs.staticFiles

静的アセットと自動的に静的最適化されたページ:

{
  type: 'STATIC_FILE'
  id: string
  filePath: string
  pathname: string
}

Middleware(outputs.middleware

Middleware関数(存在する場合):

{
  type: 'MIDDLEWARE'
  id: string
  filePath: string
  pathname: string      // 常に'/_middleware'
  sourcePage: string    // 常に'middleware'
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
    matchers?: Array<{
      source: string
      sourceRegex: string
      has: RouteHas[] | undefined
      missing: RouteHas[] | undefined
    }>
  }
}

ルート情報

onBuildCompleteroutesオブジェクトは、デプロイメント用に処理されたパターンを備えた完全なルーティング情報を提供します:

ヘッダー

各ヘッダールートには以下が含まれます:

  • source:元のルートパターン(例:/about
  • sourceRegex:リクエストをマッチングするためのコンパイルされた正規表現
  • headers:適用するヘッダーのキーと値のペア
  • has:満たされる必要があるオプションの条件
  • missing:満たされてはいけないオプションの条件
  • priority:内部ルートのオプションフラグ

リダイレクト

各リダイレクトルートには以下が含まれます:

  • source:元のルートパターン
  • sourceRegex:マッチングのためのコンパイルされた正規表現
  • destination:ターゲットURL(キャプチャされたグループを含める可能性があります)
  • statusCode:HTTPステータスコード(301、302、307、308)
  • has:オプションの正の条件
  • missing:オプションの負の条件
  • priority:内部ルートのオプションフラグ

リライト

リライトは3つのフェーズに分類されます:

  • beforeFiles:ファイルシステムの前にチェック(ページと公開ファイルを含む)
  • afterFiles:ページと公開ファイルの後だが動的ルートの前にチェック
  • fallback:他のすべてのルートの後にチェック

各リライトにはsourcesourceRegexdestinationhasmissingが含まれます。

動的ルート

動的ルートセグメント(例:[slug][...path])から生成されます。各ルートには以下が含まれます:

  • source:ルートパターン
  • sourceRegex:名前付きキャプチャグループを持つコンパイルされた正規表現
  • destination:パラメータ置換を伴う内部宛先
  • has:オプションの正の条件
  • missing:オプションの負の条件

ユースケース

アダプターの一般的なユースケースは以下のとおりです:

  • デプロイメントプラットフォーム統合:特定のホスティングプラットフォーム用にビルド出力を自動的に設定
  • アセット処理:ビルド出力を変換または最適化
  • 監視統合:ビルドメトリクスおよびルート情報を収集
  • カスタムバンドリング:プラットフォーム固有の形式で出力をパッケージ化
  • ビルド検証:出力が特定の要件を満たしていることを確認
  • ルート生成:処理されたルート情報を使用してプラットフォーム固有のルーティング設定を生成