Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
}
},
"dependencies": {
"@nuxt/kit": "^4.5.2",
"@nuxt/kit": "^4.6.0",
"@sentry/browser": "11.6.0",
"@sentry/cloudflare": "11.6.0",
"@sentry/conventions": "^0.26.0",
Expand All @@ -62,8 +62,7 @@
"@sentry/bundler-plugins": "11.6.0",
"@sentry/server-runtime-injection": "11.6.0",
"@sentry/server-utils": "11.6.0",
"@sentry/vue": "11.6.0",
"local-pkg": "^1.1.2"
"@sentry/vue": "11.6.0"
},
"devDependencies": {
"@nuxt/nitro-server": "^3.21.11",
Expand Down
108 changes: 9 additions & 99 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
import {
addPlugin,
addPluginTemplate,
addServerPlugin,
addTemplate,
addVitePlugin,
createResolver,
defineNuxtModule,
} from '@nuxt/kit';
import { addPlugin, addPluginTemplate, addTemplate, addVitePlugin, createResolver, defineNuxtModule } from '@nuxt/kit';
// Needed to make TS evaluate the augmentation of Nitro types (https://github.com/nuxt/nuxt/pull/34039)
import type {} from '@nuxt/nitro-server';

import { consoleSandbox } from '@sentry/core';
import * as path from 'path';
import type { SentryNuxtModuleOptions } from './common/types';
import {
addDynamicImportEntryFileWrapper,
addServerConfigShimWithWarning,
addSentryTopImport,
addServerConfigPlugin,
addServerConfigToBuild,
} from './vite/addServerConfig';
import { addDatabaseInstrumentation } from './vite/databaseConfig';
import { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig';
import { setupNitroServer } from './vite/nitroServer';
import { setupOrchestrion } from './vite/orchestrion';
import { setupSourceMaps } from './vite/sourceMaps';
import { addStorageInstrumentation } from './vite/storageConfig';
import { addOTelCommonJSImportAlias, findDefaultSdkInitFile, getNitroMajorVersion } from './vite/utils';
import { addOTelCommonJSImportAlias, findDefaultSdkInitFile, resolveServerApi } from './vite/utils';

export type ModuleOptions = SentryNuxtModuleOptions;
type NuxtPageSubset = { file?: string; path: string };
Expand All @@ -44,6 +26,8 @@ export default defineNuxtModule<ModuleOptions>({
return;
}

const serverApi = resolveServerApi();

const moduleOptions = {
...moduleOptionsParam,
// oxlint-disable-next-line typescript/no-deprecated -- supported until removal
Expand Down Expand Up @@ -91,7 +75,6 @@ export default defineNuxtModule<ModuleOptions>({
}

const serverConfigFile = await findDefaultSdkInitFile('server', nuxt, moduleOptions);
const isNitroV3 = (await getNitroMajorVersion(nuxt.options.rootDir)) >= 3;
const nuxtMajor = parseInt((nuxt as unknown as { _version: string })._version?.split('.')[0] ?? '3', 10);
const isMinNuxtV4 = nuxtMajor >= 4;

Expand All @@ -100,43 +83,21 @@ export default defineNuxtModule<ModuleOptions>({
// Cloudflare detection happens inside, keyed off the resolved Nitro preset.
setupOrchestrion(nuxt, !!serverConfigFile, moduleOptions.buildTimeInstrumentation);

// The deprecated inject modes replace the default in-bundle initialization until their removal
const usesDeprecatedInjectMode =
moduleOptions.autoInjectServerSentry === 'top-level-import' ||
moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import';

if (serverConfigFile) {
if (!usesDeprecatedInjectMode) {
addServerConfigPlugin(nuxt, serverConfigFile, !isNitroV3);
}

if (isNitroV3) {
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/handler.server'));
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/update-route-name.server'));
} else {
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/handler-legacy.server'));
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/update-route-name-legacy.server'));
}

addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));
setupNitroServer(nuxt, serverApi, serverConfigFile, moduleOptions);

if (isMinNuxtV4) {
addPlugin({ src: moduleDirResolver.resolve('./runtime/plugins/route-detector.server'), mode: 'server' });
} else {
addPlugin({ src: moduleDirResolver.resolve('./runtime/plugins/route-detector-legacy.server'), mode: 'server' });
}

// Preps the middleware instrumentation module.
addMiddlewareImports();
addStorageInstrumentation(nuxt, !isNitroV3);
addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions);
}

if (clientConfigFile || serverConfigFile) {
setupSourceMaps(moduleOptions, nuxt, addVitePlugin);
}

addOTelCommonJSImportAlias(nuxt, isNitroV3);
addOTelCommonJSImportAlias(nuxt, serverApi === 'nitro3');

let pagesData: NuxtPageSubset[] = [];

Expand All @@ -155,8 +116,8 @@ export default defineNuxtModule<ModuleOptions>({
// Vite virtual plugin (for the Vite SSR build, where addPlugin mode:'server' plugins are bundled)
addVitePlugin({
name: 'sentry-nuxt-pages-data-virtual',
resolveId: id => (id === pagesDataVirtualModuleId ? `\0${pagesDataVirtualModuleId}` : null),
load: id =>
resolveId: (id: string) => (id === pagesDataVirtualModuleId ? `\0${pagesDataVirtualModuleId}` : null),
load: (id: string) =>
id === `\0${pagesDataVirtualModuleId}` ? `export default ${JSON.stringify(pagesData, null, 2)};` : undefined,
});
} else {
Expand Down Expand Up @@ -186,56 +147,5 @@ export default defineNuxtModule<ModuleOptions>({
tsConfig.include.push(relativePath);
}
});

nuxt.hooks.hook('nitro:init', nitro => {
if (nuxt.options?._prepare) {
return;
}

if (serverConfigFile) {
addMiddlewareInstrumentation(nitro, isNitroV3);

if (!usesDeprecatedInjectMode) {
addServerConfigShimWithWarning(nitro);

if (moduleOptions.debug) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] Bundled \`${serverConfigFile}\` into the Nitro server build. The SDK initializes itself at server startup — no \`node --import\` preload needed.`,
);
});
}
} else {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
`[Sentry] \`autoInjectServerSentry: '${moduleOptions.autoInjectServerSentry}'\` is deprecated and will be removed in a future major version. The Sentry server config is bundled into the Nitro server build by default now. Remove the option to use the default behavior.`,
);
});

if (moduleOptions.autoInjectServerSentry === 'top-level-import') {
// Nitro 3 (in Nuxt 5) is not bundled in dev mode, so there is no build to emit into.
if (!(isNitroV3 && nitro.options.dev)) {
addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);
}
addSentryTopImport(moduleOptions, nitro);
}

if (moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import') {
addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);

if (moduleOptions.debug) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
'[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',
);
});
}
}
}
}
});
},
});
4 changes: 2 additions & 2 deletions packages/nuxt/src/vite/addServerConfig.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { existsSync } from 'node:fs';
import { basename } from 'node:path';
import { pathToFileURL } from 'node:url';
import { addServerPlugin, addTemplate, createResolver } from '@nuxt/kit';
import { addNitroPlugin, addTemplate, createResolver } from '@nuxt/kit';
import type { Nuxt } from '@nuxt/schema';
import { consoleSandbox, debug } from '@sentry/core';
import * as fs from 'fs';
Expand Down Expand Up @@ -132,7 +132,7 @@ export function addServerConfigPlugin(nuxt: Nuxt, serverConfigFile: string, isLe
`import ${JSON.stringify(runtimeFlagsTemplate.dst)};\nimport ${JSON.stringify(configPath)};\nexport default () => {};\n`,
});

addServerPlugin(configPluginTemplate.dst);
addNitroPlugin(configPluginTemplate.dst);

// Nitro v2 treeshakes side-effect-only imports outside its runtime dir, which would silently drop
// the top-level `Sentry.init` and the flag assignments.
Expand Down
6 changes: 3 additions & 3 deletions packages/nuxt/src/vite/databaseConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addServerPlugin, createResolver } from '@nuxt/kit';
import { addNitroPlugin, createResolver } from '@nuxt/kit';
import { consoleSandbox } from '@sentry/core';
import type { NitroConfig } from 'nitropack/types';
import type { SentryNuxtModuleOptions } from '../common/types';
Expand Down Expand Up @@ -43,8 +43,8 @@ export function addDatabaseInstrumentation(
});

if (isLegacyNitro) {
addServerPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database-legacy.server'));
addNitroPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database-legacy.server'));
} else {
addServerPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database.server'));
addNitroPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database.server'));
}
}
124 changes: 124 additions & 0 deletions packages/nuxt/src/vite/nitroServer.ts

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just copy-pasted code from the module.ts file

Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { addNitroPlugin, createResolver } from '@nuxt/kit';
import type { Nuxt } from '@nuxt/schema';
import { consoleSandbox } from '@sentry/core';
import type { Nitro } from 'nitropack/types';
import type { SentryNuxtModuleOptions } from '../common/types';
import {
addDynamicImportEntryFileWrapper,
addSentryTopImport,
addServerConfigPlugin,
addServerConfigShimWithWarning,
addServerConfigToBuild,
} from './addServerConfig';
import { addDatabaseInstrumentation } from './databaseConfig';
import { addMiddlewareImports, addMiddlewareInstrumentation } from './middlewareConfig';
import { addStorageInstrumentation } from './storageConfig';
import type { ServerApi } from './utils';

type NitroModuleOptions = Omit<SentryNuxtModuleOptions, 'experimental_entrypointWrappedFunctions'> &
Required<Pick<SentryNuxtModuleOptions, 'experimental_entrypointWrappedFunctions'>>;

/**
* Sets up the server SDK on the Nitro side: the server config plugin, the server plugins, and the
* middleware, storage and database instrumentation.
*
* A host on the `nuxt` server API runs no Nitro, so it gets none of this. Kit would skip each
* Nitro-only registration there with a `NUXT_B8024` warning.
*/
export function setupNitroServer(
nuxt: Nuxt,
serverApi: ServerApi,
serverConfigFile: string,
moduleOptions: NitroModuleOptions,
): void {
if (serverApi === 'nuxt') {
return;
}

const isNitroV3 = serverApi === 'nitro3';
const moduleDirResolver = createResolver(import.meta.url);
// oxlint-disable-next-line typescript/no-deprecated -- supported until removal
const injectMode = moduleOptions.autoInjectServerSentry;
// The deprecated inject modes replace the default in-bundle initialization until their removal
const deprecatedInjectMode =
injectMode === 'top-level-import' || injectMode === 'experimental_dynamic-import' ? injectMode : undefined;

if (!deprecatedInjectMode) {
addServerConfigPlugin(nuxt, serverConfigFile, !isNitroV3);
}

if (isNitroV3) {
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/handler.server'));
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/update-route-name.server'));
} else {
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/handler-legacy.server'));
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/update-route-name-legacy.server'));
}

addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));

// Preps the middleware instrumentation module.
addMiddlewareImports();
addStorageInstrumentation(nuxt, !isNitroV3);
addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions);

nuxt.hooks.hook('nitro:init', nitro => {
if (nuxt.options?._prepare) {
return;
}

addMiddlewareInstrumentation(nitro, isNitroV3);

if (deprecatedInjectMode) {
setupDeprecatedInjectMode(nitro, deprecatedInjectMode, isNitroV3, serverConfigFile, moduleOptions);
return;
}

addServerConfigShimWithWarning(nitro);

if (moduleOptions.debug) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] Bundled \`${serverConfigFile}\` into the Nitro server build. The SDK initializes itself at server startup — no \`node --import\` preload needed.`,
);
});
}
});
}

function setupDeprecatedInjectMode(
nitro: Nitro,
injectMode: 'top-level-import' | 'experimental_dynamic-import',
isNitroV3: boolean,
serverConfigFile: string,
moduleOptions: NitroModuleOptions,
): void {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
`[Sentry] \`autoInjectServerSentry: '${injectMode}'\` is deprecated and will be removed in a future major version. The Sentry server config is bundled into the Nitro server build by default now. Remove the option to use the default behavior.`,
);
});

if (injectMode === 'top-level-import') {
// Nitro 3 (in Nuxt 5) is not bundled in dev mode, so there is no build to emit into.
if (!(isNitroV3 && nitro.options.dev)) {
addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);
}
addSentryTopImport(moduleOptions, nitro);
}

if (injectMode === 'experimental_dynamic-import') {
addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);

if (moduleOptions.debug) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
'[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',
);
});
}
}
}
6 changes: 3 additions & 3 deletions packages/nuxt/src/vite/storageConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addServerPlugin, createResolver } from '@nuxt/kit';
import { addNitroPlugin, createResolver } from '@nuxt/kit';
import type { Nuxt } from '@nuxt/schema';
import { addServerTemplate } from '../vendor/server-template';

Expand All @@ -18,8 +18,8 @@ export function addStorageInstrumentation(nuxt: Nuxt, isLegacyNitro: boolean): v
});

if (isLegacyNitro) {
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage-legacy.server'));
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/storage-legacy.server'));
} else {
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));
addNitroPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));
}
}
Loading
Loading