Skip to content
Draft
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
10 changes: 0 additions & 10 deletions packages/nuxt/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type { BuildTimeOptionsBase } from '@sentry/core';
import type { init as initNode } from '@sentry/node';
import type { SentryRollupPluginOptions } from '@sentry/bundler-plugins/rollup';
import type { SentryVitePluginOptions } from '@sentry/bundler-plugins/vite';
import type { init as initVue } from '@sentry/vue';

// Omitting Vue 'app' as the Nuxt SDK will add the app instance in the client plugin (users do not have to provide this)
Expand Down Expand Up @@ -91,12 +89,4 @@ export type SentryNuxtModuleOptions = BuildTimeOptionsBase & {
* @default ['default', 'handler', 'server']
*/
experimental_entrypointWrappedFunctions?: string[];

/**
* Options to be passed directly to the Sentry Rollup Plugin (`@sentry/bundler-plugins/rollup`) and Sentry Vite Plugin (`@sentry/bundler-plugins/vite`) that ship with the Sentry Nuxt SDK.
* You can use this option to override any options the SDK passes to the Vite (for Nuxt) and Rollup (for Nitro) plugin.
*
* Please note that this option is unstable and may change in a breaking way in any release.
*/
unstable_sentryBundlerPluginOptions?: SentryRollupPluginOptions & SentryVitePluginOptions;
};
10 changes: 7 additions & 3 deletions packages/nuxt/src/vite/sourceMaps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Nuxt } from '@nuxt/schema';
import { sentryRollupPlugin, type SentryRollupPluginOptions } from '@sentry/bundler-plugins/rollup';
import { sentryVitePlugin, type SentryVitePluginOptions } from '@sentry/bundler-plugins/vite';
import { warnOnRemovedBuildOptions } from '@sentry/core';
import type { NitroConfig } from 'nitropack';
import type { Plugin } from 'vite';
import type { SentryNuxtModuleOptions } from '../common/types';
Expand All @@ -22,6 +23,10 @@ export function setupSourceMaps(
nuxt: Nuxt,
addVitePlugin: (plugin: Plugin[], options?: { dev?: boolean; build?: boolean }) => void,
): void {
// Warn here rather than in `getPluginOptions`, which runs once per bundler (Vite and Nitro's
// Rollup) and would emit the same warning twice.
warnOnRemovedBuildOptions(moduleOptions, ['unstable_sentryBundlerPluginOptions']);

const isDebug = moduleOptions.debug;

const sourceMapsEnabled = moduleOptions.sourcemaps?.disable !== true;
Expand Down Expand Up @@ -139,14 +144,13 @@ export function getPluginOptions(
name: moduleOptions.release?.name,
// Support all release options from BuildTimeOptionsBase
...moduleOptions.release,
...moduleOptions?.unstable_sentryBundlerPluginOptions?.release,
},
moduleMetadata: moduleOptions.moduleMetadata,
_metaOptions: {
telemetry: {
metaFramework: 'nuxt',
},
},
...moduleOptions?.unstable_sentryBundlerPluginOptions,

sourcemaps: {
disable: moduleOptions.sourcemaps?.disable,
Expand All @@ -157,7 +161,7 @@ export function getPluginOptions(
ignore: sourcemapsOptions.ignore ?? undefined,
filesToDeleteAfterUpload,
rewriteSources: sourcemapsOptions.rewriteSources ?? normalizePath,
...moduleOptions?.unstable_sentryBundlerPluginOptions?.sourcemaps,
resolveSourceMap: sourcemapsOptions.resolveSourceMap,
Comment thread
chargome marked this conversation as resolved.
},
};
}
Expand Down
22 changes: 13 additions & 9 deletions packages/nuxt/test/vite/buildOptions.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ describe('Sentry Nuxt build-time options type', () => {
assets: ['./dist/**/*'],
ignore: ['./dist/*.map'],
filesToDeleteAfterUpload: ['./dist/*.map'],
rewriteSources: (source: string) => source,
resolveSourceMap: (artifactPath: string) => `${artifactPath}.map`,
},
moduleMetadata: { team: 'sdk' },
release: {
name: 'test-release-1.0.0',
create: true,
Expand Down Expand Up @@ -58,19 +61,20 @@ describe('Sentry Nuxt build-time options type', () => {
autoInjectServerSentry: 'experimental_dynamic-import',
configDir: '~/custom-config',
experimental_entrypointWrappedFunctions: ['default', 'handler', 'server', 'customExport'],
};

expectTypeOf(completeOptions).toEqualTypeOf<SentryNuxtModuleOptions>();
});

it('rejects the removed `unstable_sentryBundlerPluginOptions`', () => {
const options: SentryNuxtModuleOptions = {
// @ts-expect-error - removed in v11, use the top-level build options instead
unstable_sentryBundlerPluginOptions: {
// Rollup plugin options
bundleSizeOptimizations: {
excludeDebugStatements: true,
},
// Vite plugin options
sourcemaps: {
assets: './dist/**/*',
},
sourcemaps: { assets: './dist/**/*' },
},
};

expectTypeOf(completeOptions).toEqualTypeOf<SentryNuxtModuleOptions>();
expectTypeOf(options).toEqualTypeOf<SentryNuxtModuleOptions>();
});

it('allows partial configuration', () => {
Expand Down
33 changes: 33 additions & 0 deletions packages/nuxt/test/vite/sourceMaps-nuxtHooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,39 @@ describe('setupSourceMaps hooks', () => {
mockSentryRollupPlugin.mockClear();
});

describe('removed `unstable_sentryBundlerPluginOptions`', () => {
// `getPluginOptions` runs once per bundler (Vite and Nitro's Rollup), so warning there emitted
// the same message twice. This pins it to exactly one.
it('warns exactly once, even though both bundler plugins are set up', async () => {
const { setupSourceMaps } = await import('../../src/vite/sourceMaps');
const mockNuxt = createMockNuxt({});
const { mockAddVitePlugin } = createMockAddVitePlugin();

setupSourceMaps(
// @ts-expect-error - removed in v11, but JS configs get no type checking
{ unstable_sentryBundlerPluginOptions: { org: 'override-org' } },
mockNuxt as unknown as Nuxt,
mockAddVitePlugin,
);
await mockNuxt.triggerHook('nitro:config', { rollupConfig: {} });

const removalWarnings = consoleWarnSpy.mock.calls.filter(([message]) =>
String(message).includes('unstable_sentryBundlerPluginOptions'),
);
expect(removalWarnings).toHaveLength(1);
});

it('does not warn for a config without removed options', async () => {
const { setupSourceMaps } = await import('../../src/vite/sourceMaps');
const mockNuxt = createMockNuxt({});
const { mockAddVitePlugin } = createMockAddVitePlugin();

setupSourceMaps({ org: 'my-org' }, mockNuxt as unknown as Nuxt, mockAddVitePlugin);

expect(consoleWarnSpy).not.toHaveBeenCalledWith(expect.stringContaining('unstable_'));
});
});

describe('vite plugin registration', () => {
it('calls `addVitePlugin` when setupSourceMaps is called', async () => {
const { setupSourceMaps } = await import('../../src/vite/sourceMaps');
Expand Down
32 changes: 8 additions & 24 deletions packages/nuxt/test/vite/sourceMaps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,33 +194,17 @@ describe('getPluginOptions', () => {
});
});

it('merges with unstable_sentryBundlerPluginOptions correctly', () => {
const options: SentryNuxtModuleOptions = {
org: 'base-org',
bundleSizeOptimizations: {
excludeDebugStatements: false,
},
unstable_sentryBundlerPluginOptions: {
org: 'override-org',
release: { name: 'override-release' },
sourcemaps: { assets: ['override/**/*'] },
bundleSizeOptimizations: {
excludeDebugStatements: true,
},
},
};
it('passes moduleMetadata and sourcemaps.resolveSourceMap through to the plugin', () => {
const resolveSourceMap = (artifactPath: string): string => `${artifactPath}.map`;

const result = getPluginOptions(options);
const result = getPluginOptions({
moduleMetadata: { team: 'sdk' },
sourcemaps: { resolveSourceMap },
});

expect(result).toMatchObject({
org: 'override-org',
release: { name: 'override-release' },
sourcemaps: expect.objectContaining({
assets: ['override/**/*'],
}),
bundleSizeOptimizations: {
excludeDebugStatements: true,
},
moduleMetadata: { team: 'sdk' },
sourcemaps: expect.objectContaining({ resolveSourceMap }),
});
});

Expand Down
Loading