Skip to content

Commit 398351e

Browse files
committed
add tests and support new options
1 parent 52f5e9f commit 398351e

File tree

2 files changed

+207
-54
lines changed

2 files changed

+207
-54
lines changed

packages/nuxt/src/vite/sourceMaps.ts

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@ export type SourceMapSetting = boolean | 'hidden' | 'inline';
1717
* Setup source maps for Sentry inside the Nuxt module during build time (in Vite for Nuxt and Rollup for Nitro).
1818
*/
1919
export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nuxt): void {
20+
// TODO(v11): remove deprecated options (also from SentryNuxtModuleOptions type)
21+
2022
const isDebug = moduleOptions.debug;
2123

24+
// eslint-disable-next-line deprecation/deprecation
2225
const sourceMapsUploadOptions = moduleOptions.sourceMapsUploadOptions || {};
23-
const sourceMapsEnabled = sourceMapsUploadOptions.enabled ?? true;
26+
27+
// Check new 'sourcemaps.disable' option first, then fall back to deprecated 'enabled' option
28+
// Note: 'disable' is the inverse of 'enabled'
29+
const sourceMapsEnabled =
30+
moduleOptions.sourcemaps?.disable === true
31+
? false
32+
: // eslint-disable-next-line deprecation/deprecation
33+
sourceMapsUploadOptions.enabled ?? true;
2434

2535
// In case we overwrite the source map settings, we default to deleting the files
2636
let shouldDeleteFilesFallback = { client: true, server: true };
@@ -42,6 +52,8 @@ export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu
4252

4353
if (
4454
isDebug &&
55+
!moduleOptions.sourcemaps?.filesToDeleteAfterUpload &&
56+
// eslint-disable-next-line deprecation/deprecation
4557
!sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload &&
4658
(shouldDeleteFilesFallback.client || shouldDeleteFilesFallback.server)
4759
) {
@@ -134,10 +146,13 @@ function normalizePath(path: string): string {
134146
*
135147
* Only exported for Testing purposes.
136148
*/
149+
// todo(v11): This "eslint-disable" can be removed again once we remove deprecated options.
150+
// eslint-disable-next-line complexity
137151
export function getPluginOptions(
138152
moduleOptions: SentryNuxtModuleOptions,
139153
shouldDeleteFilesFallback?: { client: boolean; server: boolean },
140154
): SentryVitePluginOptions | SentryRollupPluginOptions {
155+
// eslint-disable-next-line deprecation/deprecation
141156
const sourceMapsUploadOptions = moduleOptions.sourceMapsUploadOptions || {};
142157

143158
const shouldDeleteFilesAfterUpload = shouldDeleteFilesFallback?.client || shouldDeleteFilesFallback?.server;
@@ -148,10 +163,17 @@ export function getPluginOptions(
148163
: []),
149164
];
150165

151-
if (
152-
typeof sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload === 'undefined' &&
153-
shouldDeleteFilesAfterUpload
154-
) {
166+
// Check for filesToDeleteAfterUpload in new location first, then deprecated location
167+
const sourcemapsOptions = moduleOptions.sourcemaps || {};
168+
// eslint-disable-next-line deprecation/deprecation
169+
const deprecatedSourcemapsOptions = sourceMapsUploadOptions.sourcemaps || {};
170+
171+
const filesToDeleteAfterUpload =
172+
sourcemapsOptions.filesToDeleteAfterUpload ??
173+
// eslint-disable-next-line deprecation/deprecation
174+
deprecatedSourcemapsOptions.filesToDeleteAfterUpload;
175+
176+
if (typeof filesToDeleteAfterUpload === 'undefined' && shouldDeleteFilesAfterUpload) {
155177
consoleSandbox(() => {
156178
// eslint-disable-next-line no-console
157179
console.log(
@@ -164,16 +186,28 @@ export function getPluginOptions(
164186
}
165187

166188
return {
167-
org: sourceMapsUploadOptions.org ?? process.env.SENTRY_ORG,
168-
project: sourceMapsUploadOptions.project ?? process.env.SENTRY_PROJECT,
169-
authToken: sourceMapsUploadOptions.authToken ?? process.env.SENTRY_AUTH_TOKEN,
170-
telemetry: sourceMapsUploadOptions.telemetry ?? true,
171-
url: sourceMapsUploadOptions.url ?? process.env.SENTRY_URL,
189+
// eslint-disable-next-line deprecation/deprecation
190+
org: moduleOptions.org ?? sourceMapsUploadOptions.org ?? process.env.SENTRY_ORG,
191+
// eslint-disable-next-line deprecation/deprecation
192+
project: moduleOptions.project ?? sourceMapsUploadOptions.project ?? process.env.SENTRY_PROJECT,
193+
// eslint-disable-next-line deprecation/deprecation
194+
authToken: moduleOptions.authToken ?? sourceMapsUploadOptions.authToken ?? process.env.SENTRY_AUTH_TOKEN,
195+
// eslint-disable-next-line deprecation/deprecation
196+
telemetry: moduleOptions.telemetry ?? sourceMapsUploadOptions.telemetry ?? true,
197+
// eslint-disable-next-line deprecation/deprecation
198+
url: moduleOptions.sentryUrl ?? sourceMapsUploadOptions.url ?? process.env.SENTRY_URL,
199+
headers: moduleOptions.headers,
172200
debug: moduleOptions.debug ?? false,
173-
silent: sourceMapsUploadOptions.silent ?? false,
174-
errorHandler: sourceMapsUploadOptions.errorHandler,
201+
// eslint-disable-next-line deprecation/deprecation
202+
silent: moduleOptions.silent ?? sourceMapsUploadOptions.silent ?? false,
203+
// eslint-disable-next-line deprecation/deprecation
204+
errorHandler: moduleOptions.errorHandler ?? sourceMapsUploadOptions.errorHandler,
205+
bundleSizeOptimizations: moduleOptions.bundleSizeOptimizations, // todo: test if this can be overridden by the user
175206
release: {
176-
name: sourceMapsUploadOptions.release?.name,
207+
// eslint-disable-next-line deprecation/deprecation
208+
name: moduleOptions.release?.name ?? sourceMapsUploadOptions.release?.name,
209+
// Support all release options from BuildTimeOptionsBase
210+
...moduleOptions.release,
177211
...moduleOptions?.unstable_sentryBundlerPluginOptions?.release,
178212
},
179213
_metaOptions: {
@@ -184,13 +218,14 @@ export function getPluginOptions(
184218
...moduleOptions?.unstable_sentryBundlerPluginOptions,
185219

186220
sourcemaps: {
221+
disable: moduleOptions.sourcemaps?.disable,
187222
// The server/client files are in different places depending on the nitro preset (e.g. '.output/server' or '.netlify/functions-internal/server')
188223
// We cannot determine automatically how the build folder looks like (depends on the preset), so we have to accept that source maps are uploaded multiple times (with the vitePlugin for Nuxt and the rollupPlugin for Nitro).
189224
// If we could know where the server/client assets are located, we could do something like this (based on the Nitro preset): isNitro ? ['./.output/server/**/*'] : ['./.output/public/**/*'],
190-
assets: sourceMapsUploadOptions.sourcemaps?.assets ?? undefined,
191-
ignore: sourceMapsUploadOptions.sourcemaps?.ignore ?? undefined,
192-
filesToDeleteAfterUpload: sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload
193-
? sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload
225+
assets: sourcemapsOptions.assets ?? deprecatedSourcemapsOptions.assets ?? undefined,
226+
ignore: sourcemapsOptions.ignore ?? deprecatedSourcemapsOptions.ignore ?? undefined,
227+
filesToDeleteAfterUpload: filesToDeleteAfterUpload
228+
? filesToDeleteAfterUpload
194229
: shouldDeleteFilesFallback?.server || shouldDeleteFilesFallback?.client
195230
? fallbackFilesToDelete
196231
: undefined,

packages/nuxt/test/vite/sourceMaps.test.ts

Lines changed: 155 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@ describe('getPluginOptions', () => {
1818
process.env = {};
1919
});
2020

21-
it('uses environment variables when no moduleOptions are provided', () => {
22-
const defaultEnv = {
21+
it('uses environment variables as fallback when no moduleOptions are provided', () => {
22+
process.env = {
2323
SENTRY_ORG: 'default-org',
2424
SENTRY_PROJECT: 'default-project',
2525
SENTRY_AUTH_TOKEN: 'default-token',
2626
SENTRY_URL: 'https://santry.io',
2727
};
2828

29-
process.env = { ...defaultEnv };
30-
3129
const options = getPluginOptions({} as SentryNuxtModuleOptions);
3230

3331
expect(options).toEqual(
@@ -110,46 +108,159 @@ describe('getPluginOptions', () => {
110108
);
111109
});
112110

113-
it('overrides options that were undefined with options from unstable_sentryRollupPluginOptions', () => {
114-
const customOptions: SentryNuxtModuleOptions = {
111+
it('prioritizes new BuildTimeOptionsBase options over deprecated ones', () => {
112+
const options: SentryNuxtModuleOptions = {
113+
// New options
114+
org: 'new-org',
115+
project: 'new-project',
116+
authToken: 'new-token',
117+
sentryUrl: 'https://new.sentry.io',
118+
telemetry: false,
119+
silent: true,
120+
debug: true,
121+
sourcemaps: {
122+
assets: ['new-assets/**/*'],
123+
ignore: ['new-ignore.js'],
124+
filesToDeleteAfterUpload: ['new-delete.js'],
125+
},
126+
release: {
127+
name: 'test-release',
128+
create: false,
129+
finalize: true,
130+
dist: 'build-123',
131+
vcsRemote: 'upstream',
132+
setCommits: { auto: true },
133+
deploy: { env: 'production' },
134+
},
135+
bundleSizeOptimizations: { excludeTracing: true },
136+
137+
// Deprecated options (should be ignored)
115138
sourceMapsUploadOptions: {
116-
org: 'custom-org',
117-
project: 'custom-project',
139+
org: 'old-org',
140+
project: 'old-project',
141+
authToken: 'old-token',
142+
url: 'https://old.sentry.io',
143+
telemetry: true,
144+
silent: false,
118145
sourcemaps: {
119-
assets: ['custom-assets/**/*'],
120-
filesToDeleteAfterUpload: ['delete-this.js'],
146+
assets: ['old-assets/**/*'],
147+
ignore: ['old-ignore.js'],
148+
filesToDeleteAfterUpload: ['old-delete.js'],
121149
},
122-
url: 'https://santry.io',
150+
release: { name: 'old-release' },
123151
},
152+
};
153+
154+
const result = getPluginOptions(options);
155+
156+
expect(result).toMatchObject({
157+
org: 'new-org',
158+
project: 'new-project',
159+
authToken: 'new-token',
160+
url: 'https://new.sentry.io',
161+
telemetry: false,
162+
silent: true,
124163
debug: true,
125-
unstable_sentryBundlerPluginOptions: {
126-
org: 'unstable-org',
164+
bundleSizeOptimizations: { excludeTracing: true },
165+
release: {
166+
name: 'test-release',
167+
create: false,
168+
finalize: true,
169+
dist: 'build-123',
170+
vcsRemote: 'upstream',
171+
setCommits: { auto: true },
172+
deploy: { env: 'production' },
173+
},
174+
sourcemaps: expect.objectContaining({
175+
assets: ['new-assets/**/*'],
176+
ignore: ['new-ignore.js'],
177+
filesToDeleteAfterUpload: ['new-delete.js'],
178+
}),
179+
});
180+
});
181+
182+
it('falls back to deprecated options when new ones are undefined', () => {
183+
const options: SentryNuxtModuleOptions = {
184+
debug: true,
185+
sourceMapsUploadOptions: {
186+
org: 'deprecated-org',
187+
project: 'deprecated-project',
188+
authToken: 'deprecated-token',
189+
url: 'https://deprecated.sentry.io',
190+
telemetry: false,
127191
sourcemaps: {
128-
assets: ['unstable-assets/**/*'],
192+
assets: ['deprecated/**/*'],
129193
},
130-
release: {
131-
name: 'test-release',
194+
release: { name: 'deprecated-release' },
195+
},
196+
};
197+
198+
const result = getPluginOptions(options);
199+
200+
expect(result).toMatchObject({
201+
org: 'deprecated-org',
202+
project: 'deprecated-project',
203+
authToken: 'deprecated-token',
204+
url: 'https://deprecated.sentry.io',
205+
telemetry: false,
206+
debug: true,
207+
release: { name: 'deprecated-release' },
208+
sourcemaps: expect.objectContaining({
209+
assets: ['deprecated/**/*'],
210+
}),
211+
});
212+
});
213+
214+
it('supports bundleSizeOptimizations', () => {
215+
const options: SentryNuxtModuleOptions = {
216+
bundleSizeOptimizations: {
217+
excludeDebugStatements: true,
218+
excludeTracing: true,
219+
excludeReplayShadowDom: true,
220+
excludeReplayIframe: true,
221+
excludeReplayWorker: true,
222+
},
223+
};
224+
225+
const result = getPluginOptions(options);
226+
227+
expect(result.bundleSizeOptimizations).toEqual({
228+
excludeDebugStatements: true,
229+
excludeTracing: true,
230+
excludeReplayShadowDom: true,
231+
excludeReplayIframe: true,
232+
excludeReplayWorker: true,
233+
});
234+
});
235+
236+
it('merges with unstable_sentryBundlerPluginOptions correctly', () => {
237+
const options: SentryNuxtModuleOptions = {
238+
org: 'base-org',
239+
bundleSizeOptimizations: {
240+
excludeDebugStatements: false,
241+
},
242+
unstable_sentryBundlerPluginOptions: {
243+
org: 'override-org',
244+
release: { name: 'override-release' },
245+
sourcemaps: { assets: ['override/**/*'] },
246+
bundleSizeOptimizations: {
247+
excludeDebugStatements: true,
132248
},
133-
url: 'https://suntry.io',
134249
},
135250
};
136-
const options = getPluginOptions(customOptions);
137-
expect(options).toEqual(
138-
expect.objectContaining({
139-
debug: true,
140-
org: 'unstable-org',
141-
project: 'custom-project',
142-
sourcemaps: expect.objectContaining({
143-
assets: ['unstable-assets/**/*'],
144-
filesToDeleteAfterUpload: ['delete-this.js'],
145-
rewriteSources: expect.any(Function),
146-
}),
147-
release: expect.objectContaining({
148-
name: 'test-release',
149-
}),
150-
url: 'https://suntry.io',
251+
252+
const result = getPluginOptions(options);
253+
254+
expect(result).toMatchObject({
255+
org: 'override-org',
256+
release: { name: 'override-release' },
257+
sourcemaps: expect.objectContaining({
258+
assets: ['override/**/*'],
151259
}),
152-
);
260+
bundleSizeOptimizations: {
261+
excludeDebugStatements: true,
262+
},
263+
});
153264
});
154265

155266
it.each([
@@ -185,12 +296,19 @@ describe('getPluginOptions', () => {
185296
serverFallback: false,
186297
customOptions: {
187298
sourceMapsUploadOptions: {
188-
sourcemaps: {
189-
filesToDeleteAfterUpload: ['custom/path/**/*.map'],
190-
},
299+
sourcemaps: { filesToDeleteAfterUpload: ['deprecated/path/**/*.map'] },
191300
},
192301
},
193-
expectedFilesToDelete: ['custom/path/**/*.map'],
302+
expectedFilesToDelete: ['deprecated/path/**/*.map'],
303+
},
304+
{
305+
name: 'no fallback, but custom filesToDeleteAfterUpload is provided',
306+
clientFallback: false,
307+
serverFallback: false,
308+
customOptions: {
309+
sourcemaps: { filesToDeleteAfterUpload: ['new-custom/path/**/*.map'] },
310+
},
311+
expectedFilesToDelete: ['new-custom/path/**/*.map'],
194312
},
195313
{
196314
name: 'no fallback, both source maps explicitly false and no custom filesToDeleteAfterUpload',

0 commit comments

Comments
 (0)