仪表化 (Instrumentation)

如果您从项目根目录(或使用 src 文件夹时的 src 目录)下的 instrumentation.ts(或 .js)文件中导出一个名为 register 的函数,每当新的 Next.js 服务器实例启动时,我们都将调用该函数。

须知

  • 此功能为实验性。要使用它,您必须在 next.config.js 中明确启用:experimental.instrumentationHook = true;
  • instrumentation 文件应位于项目根目录,而非 apppages 目录内。如果使用 src 文件夹,请将文件置于 src 中与 pagesapp 同级的位置
  • 如果使用 pageExtensions 配置选项 添加后缀,您也需要相应更新 instrumentation 文件名
  • 我们创建了一个基础的 with-opentelemetry 示例供您参考

当您的 register 函数部署后,它将在每次冷启动时被调用(但在每个环境中仅调用一次)。

有时,由于文件导入会产生副作用,在代码中导入文件可能很有用。例如,您可能导入一个定义了全局变量的文件,但从未在代码中显式使用该导入文件。您仍然可以访问该包声明的全局变量。

您可以在 instrumentation.ts 中导入具有副作用的文件,如下例所示,这些文件可能需要在 register 函数中使用:

import { init } from 'package-init'

export function register() {
  init()
}

不过,我们建议通过 register 函数内部的 import 来导入具有副作用的文件。以下示例展示了在 register 函数中使用 import 的基本用法:

export async function register() {
  await import('package-with-side-effect')
}

通过这种方式,您可以将所有副作用代码集中管理,避免因文件导入导致的意外问题。

我们会在所有环境中调用 register,因此需要条件导入那些不支持同时运行在 edgenodejs 环境下的代码。您可以使用环境变量 NEXT_RUNTIME 来获取当前环境。导入环境特定代码的示例如下:

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation-node')
  }

  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('./instrumentation-edge')
  }
}