Skip to content

experimental.adapterPath

Next.js 提供了一个实验性 API,允许你创建自定义适配器来集成到构建过程中。这对于需要修改 Next.js 配置或处理构建输出的部署平台或自定义构建集成非常有用。

¥Next.js provides an experimental API that allows you to create custom adapters to hook into the build process. This is useful for deployment platforms or custom build integrations that need to modify the Next.js configuration or process the build output.

配置

¥Configuration

要使用适配器,请在 experimental.adapterPath 中指定适配器模块的路径:

¥To use an adapter, specify the path to your adapter module in experimental.adapterPath:

创建适配器

¥Creating an Adapter

适配器是一个导出实现 NextAdapter 接口的对象的模块:

¥An adapter is a module that exports an object implementing the NextAdapter interface:

typescript
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
}

基本适配器结构

¥Basic Adapter Structure

以下是一个最小适配器示例:

¥Here's a minimal adapter example:

API 参考

¥API Reference

modifyConfig(config, context)

任何加载 next.config 的 CLI 命令都会调用此方法,以允许修改配置。

¥Called for any CLI command that loads the next.config to allow modification of the configuration.

参数:

¥Parameters:

  • config:完整的 Next.js 配置对象

    ¥config: The complete Next.js configuration object

  • context.phase:当前构建阶段(参见 phases

    ¥context.phase: The current build phase (see phases)

返回结果:修改后的配置对象(可以是异步的)。

¥Returns: The modified configuration object (can be async)

onBuildComplete(context)

在构建过程完成后调用,提供有关路由和输出的详细信息。

¥Called after the build process completes with detailed information about routes and outputs.

参数:

¥Parameters:

  • routes:包含路由清单的对象,用于处理标头、重定向、重写和动态路由。

    ¥routes: Object containing route manifests for headers, redirects, rewrites, and dynamic routes

    • routes.headers:包含 sourcesourceRegexheadershasmissing 和可选 priority 字段的头部路由对象数组

      ¥routes.headers: Array of header route objects with source, sourceRegex, headers, has, missing, and optional priority fields

    • routes.redirects:包含 sourcesourceRegexdestinationstatusCodehasmissing 和可选 priority 字段的重定向路由对象数组

      ¥routes.redirects: Array of redirect route objects with source, sourceRegex, destination, statusCode, has, missing, and optional priority fields

    • routes.rewrites:包含 beforeFilesafterFilesfallback 数组的对象,每个数组都包含带有 sourcesourceRegexdestinationhasmissing 字段的重写路由对象。

      ¥routes.rewrites: Object with beforeFiles, afterFiles, and fallback arrays, each containing rewrite route objects with source, sourceRegex, destination, has, and missing fields

    • routes.dynamicRoutes:包含 sourcesourceRegexdestinationhasmissing 字段的动态路由对象数组

      ¥routes.dynamicRoutes: Array of dynamic route objects with source, sourceRegex, destination, has, and missing fields

  • outputs:按类型整理的所有构建输出的详细信息

    ¥outputs: Detailed information about all build outputs organized by type

  • projectDir:Next.js 项目目录的绝对路径

    ¥projectDir: Absolute path to the Next.js project directory

  • repoRoot:检测到的仓库根目录的绝对路径

    ¥repoRoot: Absolute path to the detected repository root

  • distDir:构建输出目录的绝对路径

    ¥distDir: Absolute path to the build output directory

  • config:最终的 Next.js 配置(已应用 modifyConfig

    ¥config: The final Next.js configuration (with modifyConfig applied)

  • nextVersion:正在使用的 Next.js 版本

    ¥nextVersion: Version of Next.js being used

  • buildId:当前构建的唯一标识符

    ¥buildId: Unique identifier for the current build

输出类型

¥Output Types

outputs 对象包含不同输出类型的数组:

¥The outputs object contains arrays of different output types:

页面 (outputs.pages)

¥Pages (outputs.pages)

pages/ 目录创建 React 页面:

¥React pages from the pages/ directory:

typescript
{
  type: 'PAGES'
  id: string           // Route identifier
  filePath: string     // Path to the built file
  pathname: string     // URL pathname
  sourcePage: string   // Original source file path in pages/ directory
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>  // Traced dependencies (key: relative path from repo root, value: absolute path)
  wasmAssets?: Record<string, string>  // Bundled wasm files (key: name, value: absolute path)
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>  // Environment variables (edge runtime only)
  }
}

API 路由 (outputs.pagesApi)

¥API Routes (outputs.pagesApi)

来自 pages/api/ 的 API 路由:

¥API routes from pages/api/:

typescript
{
  type: 'PAGES_API'
  id: string
  filePath: string
  pathname: string
  sourcePage: string   // Original relative source file path
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
  }
}

应用页面 (outputs.appPages)

¥App Pages (outputs.appPages)

使用 page.{js,ts,jsx,tsx}app/ 目录创建 React 页面:

¥React pages from the app/ directory with page.{js,ts,jsx,tsx}:

typescript
{
  type: 'APP_PAGE'
  id: string
  filePath: string
  pathname: string     // Includes .rsc suffix for RSC routes
  sourcePage: string   // Original relative source file path
  runtime: 'nodejs' | 'edge'
  assets: Record<string, string>
  wasmAssets?: Record<string, string>
  config: {
    maxDuration?: number
    preferredRegion?: string | string[]
    env?: Record<string, string>
  }
}

应用路由 (outputs.appRoutes)

¥App Routes (outputs.appRoutes)

通过 app/route.{js,ts,jsx,tsx} 实现 API 和元数据路由:

¥API and metadata routes from app/ with route.{js,ts,jsx,tsx}:

typescript
{
  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)

¥Prerenders (outputs.prerenders)

启用 ISR 的路由和静态预渲染:

¥ISR-enabled routes and static prerenders:

typescript
{
  type: 'PRERENDER'
  id: string
  pathname: string
  parentOutputId: string  // ID of the source page/route
  groupId: number        // Revalidation group identifier (prerenders with same groupId revalidate together)
  pprChain?: {
    headers: Record<string, string>  // PPR chain headers (e.g., 'x-nextjs-resume': '1')
  }
  parentFallbackMode?: 'blocking' | false | null  // Fallback mode from getStaticPaths
  fallback?: {
    filePath: string
    initialStatus?: number
    initialHeaders?: Record<string, string | string[]>
    initialExpiration?: number
    initialRevalidate?: number
    postponedState?: string  // PPR postponed state
  }
  config: {
    allowQuery?: string[]     // Allowed query parameters
    allowHeader?: string[]    // Allowed headers for ISR
    bypassFor?: RouteHas[]    // Cache bypass conditions
    renderingMode?: RenderingMode
    bypassToken?: string
  }
}

静态文件 (outputs.staticFiles)

¥Static Files (outputs.staticFiles)

静态资源和自动静态优化的页面:

¥Static assets and auto-statically optimized pages:

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

中间件 (outputs.middleware)

¥Middleware (outputs.middleware)

中间件函数(如果存在):

¥Middleware function (if present):

typescript
{
  type: 'MIDDLEWARE'
  id: string
  filePath: string
  pathname: string      // Always '/_middleware'
  sourcePage: string    // Always '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
    }>
  }
}

路由信息

¥Routes Information

onBuildComplete 中的 routes 对象提供完整的路由信息​​,其中包含已处理好的模式,可供部署:

¥The routes object in onBuildComplete provides complete routing information with processed patterns ready for deployment:

标头

¥Headers

每个路由标头包含:

¥Each header route includes:

  • source:原始路由模式(例如,/about

    ¥source: Original route pattern (e.g., /about)

  • sourceRegex:用于匹配请求的已编译正则表达式

    ¥sourceRegex: Compiled regex for matching requests

  • headers:要应用的键值对标头

    ¥headers: Key-value pairs of headers to apply

  • has:必须满足的可选条件

    ¥has: Optional conditions that must be met

  • missing:不得满足的可选条件

    ¥missing: Optional conditions that must not be met

  • priority:内部路由的可选标志

    ¥priority: Optional flag for internal routes

重定向

¥Redirects

每个重定向路由包含:

¥Each redirect route includes:

  • source:原始路由模式

    ¥source: Original route pattern

  • sourceRegex:用于匹配的编译正则表达式

    ¥sourceRegex: Compiled regex for matching

  • destination:目标 URL(可以包含捕获的组)

    ¥destination: Target URL (can include captured groups)

  • statusCode:HTTP 状态码(301、302、307、308)

    ¥statusCode: HTTP status code (301, 302, 307, 308)

  • has:可选肯定条件

    ¥has: Optional positive conditions

  • missing:可选否定条件

    ¥missing: Optional negative conditions

  • priority:内部路由的可选标志

    ¥priority: Optional flag for internal routes

重写

¥Rewrites

重写分为三个阶段:

¥Rewrites are categorized into three phases:

  • beforeFiles:在文件系统(包括页面和公共文件)之前检查。

    ¥beforeFiles: Checked before filesystem (including pages and public files)

  • afterFiles:在页面/公共文件之后、动态路由之前检查。

    ¥afterFiles: Checked after pages/public files but before dynamic routes

  • fallback:在所有其他路由之后检查。

    ¥fallback: Checked after all other routes

每次重写都包含 sourcesourceRegexdestinationhasmissing

¥Each rewrite includes source, sourceRegex, destination, has, and missing.

动态路由

¥Dynamic Routes

由动态路由段(例如 [slug][...path])生成。每个包含:

¥Generated from dynamic route segments (e.g., [slug], [...path]). Each includes:

  • source:路由模式

    ¥source: Route pattern

  • sourceRegex:带有命名捕获组的已编译正则表达式

    ¥sourceRegex: Compiled regex with named capture groups

  • destination:带参数替换的内部目标

    ¥destination: Internal destination with parameter substitution

  • has:可选肯定条件

    ¥has: Optional positive conditions

  • missing:可选否定条件

    ¥missing: Optional negative conditions

用例

¥Use Cases

适配器的常见用例包括:

¥Common use cases for adapters include:

  • 部署平台集成:自动为特定托管平台配置构建输出。

    ¥Deployment Platform Integration: Automatically configure build outputs for specific hosting platforms

  • 资源处理:转换或优化构建输出

    ¥Asset Processing: Transform or optimize build outputs

  • 监控集成:收集构建指标和路由信息

    ¥Monitoring Integration: Collect build metrics and route information

  • 自定义打包:以平台特定格式输出包

    ¥Custom Bundling: Package outputs in platform-specific formats

  • 构建验证:确保输出符合特定要求

    ¥Build Validation: Ensure outputs meet specific requirements

  • 路由生成:使用处理后的路由信息​​生成平台特定的路由配置。

    ¥Route Generation: Use processed route information to generate platform-specific routing configs