Пошук уроків, статей та іншого контенту
Додайте instrumentation.ts для запуску коду під час ініціалізації сервера та підключення інструментів спостереження.
instrumentation.tsinstrumentation.ts — це спеціальний файл-конвенція Next.js для виконання коду під час ініціалізації серверного екземпляра.
Його використовують, щоб:
підключити систему логування;
ініціалізувати метрики й трасування;
налаштувати SDK для спостереження за застосунком;
виконати одноразову підготовку серверного середовища.
Файл не є React-компонентом і не виконується в браузері. Next.js запускає його на сервері під час старту застосунку.
Створіть instrumentation.ts у корені проєкту:
my-next-app/
├── app/
├── public/
├── instrumentation.ts
├── next.config.ts
└── package.jsonЯкщо застосунок використовує директорію src, файл можна розмістити в ній:
my-next-app/
├── src/
│ ├── app/
│ └── instrumentation.ts
├── public/
└── package.jsonВикористовуйте лише один файл instrumentation.ts.
registerОсновна точка входу — експортована функція register:
export async function register() {
// Код виконується під час ініціалізації сервера
}Функція може бути синхронною або асинхронною. Асинхронний варіант зручний, коли SDK спостереження потрібно імпортувати або налаштувати асинхронно.
// instrumentation.ts
export async function register(): Promise<void> {
const runtime = process.env.NEXT_RUNTIME ?? "unknown";
console.info(`[instrumentation] Запуск у середовищі: ${runtime}`);
if (runtime === "nodejs") {
console.info("[instrumentation] Node.js спостереження ініціалізовано");
}
if (runtime === "edge") {
console.info("[instrumentation] Edge спостереження ініціалізовано");
}
}Після запуску Next.js у серверному логові з’явиться повідомлення з назвою середовища виконання.
Next.js може запускати серверний код у різних середовищах:
nodejs — стандартне Node.js-середовище;
edge — Edge Runtime;
невизначене значення — у ситуаціях, коли середовище ще не встановлене або використовується нестандартний сценарій.
Для SDK спостереження часто існують окремі реалізації для Node.js та Edge Runtime. Перевіряйте NEXT_RUNTIME, перш ніж підключати відповідний код.
// instrumentation.ts
export async function register(): Promise<void> {
if (process.env.NEXT_RUNTIME === "nodejs") {
await initializeNodeObservability();
return;
}
if (process.env.NEXT_RUNTIME === "edge") {
await initializeEdgeObservability();
}
}
async function initializeNodeObservability(): Promise<void> {
console.info("[instrumentation] Ініціалізація Node.js інструментів");
// Тут можна підключити Node.js SDK спостереження.
}
async function initializeEdgeObservability(): Promise<void> {
console.info("[instrumentation] Ініціалізація Edge інструментів");
// Тут можна підключити Edge-сумісний SDK спостереження.
}Такий поділ важливий, оскільки Node.js API не завжди доступні в Edge Runtime.
Інструменти спостереження можуть використовувати Node.js-специфічні модулі. Щоб вони не потрапили до Edge-коду, підключайте їх динамічно лише в потрібному середовищі.
// instrumentation.ts
export async function register(): Promise<void> {
if (process.env.NEXT_RUNTIME === "nodejs") {
const { initializeNodeObservability } = await import(
"./src/observability/node"
);
await initializeNodeObservability();
}
if (process.env.NEXT_RUNTIME === "edge") {
const { initializeEdgeObservability } = await import(
"./src/observability/edge"
);
await initializeEdgeObservability();
}
}Наприклад, файл src/observability/node.ts може мати такий вигляд:
// src/observability/node.ts
let initialized = false;
export async function initializeNodeObservability(): Promise<void> {
if (initialized) {
return;
}
initialized = true;
console.info("[observability] Node.js інструменти підключено");
// Тут викликається ініціалізація конкретного SDK:
// логування, метрики або розподілене трасування.
}Перевірка initialized захищає від повторної ініціалізації в середовищах, де серверний код може перезапускатися під час розробки.
Конкретний SDK потрібно ініціалізувати всередині register або функції, яку він викликає:
// instrumentation.ts
export async function register(): Promise<void> {
if (process.env.NEXT_RUNTIME !== "nodejs") {
return;
}
const { initializeObservability } = await import(
"./src/observability/node"
);
await initializeObservability();
}// src/observability/node.ts
let isInitialized = false;
export async function initializeObservability(): Promise<void> {
if (isInitialized) {
return;
}
isInitialized = true;
console.info("[observability] SDK готовий до збору даних");
// Тут розміщується код ініціалізації SDK спостереження.
}Переваги такого підходу:
instrumentation.ts залишається коротким;
код SDK завантажується лише на сервері;
Node.js та Edge Runtime можна налаштовувати окремо;
логіку легко тестувати та змінювати незалежно від Next.js.
registerregister виконується під час запуску серверного екземпляра Next.js, а не для кожного HTTP-запиту.
Тому в цій функції доречно:
створювати глобальні клієнти SDK;
реєструвати інструменти трасування;
налаштовувати системне логування;
виконувати одноразову ініціалізацію.
У цій функції не варто:
читати дані конкретного користувача;
обробляти параметри HTTP-запиту;
виконувати запит до бази даних для кожного запуску без потреби;
розміщувати код, який має виконуватися для кожного запиту.
Під час горизонтального масштабування кожен процес або екземпляр застосунку може виконати register окремо. Тому ініціалізація має бути безпечною для повторного виконання.
instrumentation.ts не призначений для клієнтського JavaScript. Не імпортуйте його в компоненти або клієнтські модулі.
Код на кшталт роботи з файловою системою, мережевими сокетами або іншими Node.js-модулями повинен запускатися лише після перевірки:
if (process.env.NEXT_RUNTIME === "nodejs") {
// Node.js-специфічний код
}Повторне створення клієнта інструмента спостереження може призвести до:
дублювання метрик;
повторного надсилання логів;
зайвих з’єднань;
помилок під час завершення процесу.
Для захисту використовуйте прапорець або інший механізм одноразової ініціалізації.
Next.js розпізнає саме файл:
instrumentation.tsНазви instrumentation-hook.ts, instrument.ts або instrumentation.server.ts автоматично не замінюють його.
srcЯкщо файл лежить у довільній директорії, Next.js не використає його як instrumentation-файл.
Next.js очікує експорт register:
export async function register() {
// ...
}Звичайна функція без експорту не буде викликана.
Такий імпорт може спричинити проблему в Edge Runtime:
import nodeOnlyLibrary from "node-only-library";Краще завантажувати Node.js-залежність динамічно після перевірки NEXT_RUNTIME.
register розміщено логіку запитуregister не є middleware і не виконується для кожного запиту. Для запитозалежної логіки потрібні інші механізми Next.js.
instrumentation.ts — файл-конвенція Next.js для серверної ініціалізації.
Основна функція в ньому — експортована register.
Файл можна розмістити в корені проєкту або в src.
Через NEXT_RUNTIME можна розділити Node.js- та Edge-логіку.
Інструменти спостереження краще підключати динамічним імпортом у відповідному середовищі.
register призначений для одноразової підготовки сервера, а не для обробки окремих запитів.
Ініціалізація зовнішніх SDK має бути захищена від повторного виконання.