Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(nuxt): Don't run source maps related code on Nuxt "prepare"#18936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -35,7 +35,7 @@ export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu | ||
| let shouldDeleteFilesFallback = { client: true, server: true }; | ||
| nuxt.hook('modules:done', () => { | ||
| if (sourceMapsEnabled && !nuxt.options.dev) { | ||
| if (sourceMapsEnabled && !nuxt.options.dev && !nuxt.options?._prepare) { | ||
| // Changing this setting will propagate: | ||
| // - for client to viteConfig.build.sourceMap | ||
| // - for server to viteConfig.build.sourceMap and nitro.sourceMap | ||
| @@ -49,23 +49,35 @@ export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu | ||
| server: previousSourceMapSettings.server === 'unset', | ||
| }; | ||
| if ( | ||
| isDebug && | ||
| !moduleOptions.sourcemaps?.filesToDeleteAfterUpload && | ||
| // eslint-disable-next-line deprecation/deprecation | ||
| !sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload && | ||
| (shouldDeleteFilesFallback.client || shouldDeleteFilesFallback.server) | ||
| ) { | ||
| // eslint-disable-next-line no-console | ||
| console.log( | ||
| "[Sentry] As Sentry enabled `'hidden'` source maps, source maps will be automatically deleted after uploading them to Sentry.", | ||
| ); | ||
| if (isDebug && (shouldDeleteFilesFallback.client || shouldDeleteFilesFallback.server)) { | ||
| const enabledDeleteFallbacks = | ||
| shouldDeleteFilesFallback.client && shouldDeleteFilesFallback.server | ||
| ? 'client-side and server-side' | ||
| : shouldDeleteFilesFallback.server | ||
| ? 'server-side' | ||
| : 'client-side'; | ||
| if ( | ||
| !moduleOptions.sourcemaps?.filesToDeleteAfterUpload && | ||
| // eslint-disable-next-line deprecation/deprecation | ||
| !sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload | ||
| ) { | ||
| // eslint-disable-next-line no-console | ||
| console.log( | ||
| `[Sentry] We enabled \`'hidden'\` source maps for your ${enabledDeleteFallbacks} build. Source map files will be automatically deleted after uploading them to Sentry.`, | ||
| ); | ||
| } else { | ||
| // eslint-disable-next-line no-console | ||
| console.log( | ||
| `[Sentry] We enabled \`'hidden'\` source maps for your ${enabledDeleteFallbacks} build. Source map files will be deleted according to your \`sourcemaps.filesToDeleteAfterUpload\` configuration. To use automatic deletion instead, leave \`filesToDeleteAfterUpload\` empty.`, | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| nuxt.hook('vite:extendConfig', async (viteConfig, env) => { | ||
| if (sourceMapsEnabled && viteConfig.mode !== 'development') { | ||
| if (sourceMapsEnabled && viteConfig.mode !== 'development' && !nuxt.options?._prepare) { | ||
| const runtime = env.isServer ? 'server' : env.isClient ? 'client' : undefined; | ||
| const nuxtSourceMapSetting = extractNuxtSourceMapSetting(nuxt, runtime); | ||
| @@ -99,7 +111,7 @@ export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu | ||
| }); | ||
| nuxt.hook('nitro:config', (nitroConfig: NitroConfig) => { | ||
| if (sourceMapsEnabled && !nitroConfig.dev) { | ||
s1gr1d marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (sourceMapsEnabled && !nitroConfig.dev && !nuxt.options?._prepare) { | ||
| if (!nitroConfig.rollupConfig) { | ||
| nitroConfig.rollupConfig = {}; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| import type { Nuxt } from '@nuxt/schema'; | ||
| import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
| import type { SourceMapSetting } from '../../src/vite/sourceMaps'; | ||
| describe('setupSourceMaps hooks', () => { | ||
| const mockSentryVitePlugin = vi.fn(() => ({ name: 'sentry-vite-plugin' })); | ||
| const mockSentryRollupPlugin = vi.fn(() => ({ name: 'sentry-rollup-plugin' })); | ||
| const consoleLogSpy = vi.spyOn(console, 'log'); | ||
| const consoleWarnSpy = vi.spyOn(console, 'warn'); | ||
| beforeAll(() => { | ||
| vi.doMock('@sentry/vite-plugin', () => ({ | ||
| sentryVitePlugin: mockSentryVitePlugin, | ||
| })); | ||
| vi.doMock('@sentry/rollup-plugin', () => ({ | ||
| sentryRollupPlugin: mockSentryRollupPlugin, | ||
| })); | ||
| }); | ||
| afterAll(() => { | ||
| consoleLogSpy.mockRestore(); | ||
| consoleWarnSpy.mockRestore(); | ||
| vi.doUnmock('@sentry/vite-plugin'); | ||
| vi.doUnmock('@sentry/rollup-plugin'); | ||
| }); | ||
| beforeEach(() => { | ||
| consoleLogSpy.mockClear(); | ||
| consoleWarnSpy.mockClear(); | ||
| mockSentryVitePlugin.mockClear(); | ||
| mockSentryRollupPlugin.mockClear(); | ||
| }); | ||
| type HookCallback = (...args: unknown[]) => void | Promise<void>; | ||
| function createMockNuxt(options: { | ||
| _prepare?: boolean; | ||
| dev?: boolean; | ||
| sourcemap?: SourceMapSetting | { server?: SourceMapSetting; client?: SourceMapSetting }; | ||
| }) { | ||
| const hooks: Record<string, HookCallback[]> = {}; | ||
| return { | ||
| options: { | ||
| _prepare: options._prepare ?? false, | ||
| dev: options.dev ?? false, | ||
| sourcemap: options.sourcemap ?? { server: undefined, client: undefined }, | ||
| }, | ||
| hook: (name: string, callback: HookCallback) => { | ||
| hooks[name] = hooks[name] || []; | ||
| hooks[name].push(callback); | ||
| }, | ||
| // Helper to trigger hooks in tests | ||
| triggerHook: async (name: string, ...args: unknown[]) => { | ||
| const callbacks = hooks[name] || []; | ||
| for (const callback of callbacks) { | ||
| await callback(...args); | ||
| } | ||
| }, | ||
| }; | ||
| } | ||
| it('should not call any source map related functions in nuxt prepare mode', async () => { | ||
| const { setupSourceMaps } = await import('../../src/vite/sourceMaps'); | ||
| const mockNuxt = createMockNuxt({ _prepare: true }); | ||
| setupSourceMaps({ debug: true }, mockNuxt as unknown as Nuxt); | ||
| await mockNuxt.triggerHook('modules:done'); | ||
| await mockNuxt.triggerHook( | ||
| 'vite:extendConfig', | ||
| { build: {}, plugins: [], mode: 'production' }, | ||
| { isServer: true, isClient: false }, | ||
| ); | ||
| await mockNuxt.triggerHook('nitro:config', { rollupConfig: { plugins: [] }, dev: false }); | ||
| expect(mockSentryVitePlugin).not.toHaveBeenCalled(); | ||
| expect(mockSentryRollupPlugin).not.toHaveBeenCalled(); | ||
| expect(consoleLogSpy).not.toHaveBeenCalledWith(expect.stringContaining('[Sentry]')); | ||
| }); | ||
| it('should call source map related functions when not in prepare mode', async () => { | ||
| const { setupSourceMaps } = await import('../../src/vite/sourceMaps'); | ||
| const mockNuxt = createMockNuxt({ _prepare: false, dev: false }); | ||
| setupSourceMaps({ debug: true }, mockNuxt as unknown as Nuxt); | ||
| await mockNuxt.triggerHook('modules:done'); | ||
| const viteConfig = { build: {}, plugins: [] as unknown[], mode: 'production' }; | ||
| await mockNuxt.triggerHook('vite:extendConfig', viteConfig, { isServer: true, isClient: false }); | ||
| const nitroConfig = { rollupConfig: { plugins: [] as unknown[], output: {} }, dev: false }; | ||
| await mockNuxt.triggerHook('nitro:config', nitroConfig); | ||
| expect(mockSentryVitePlugin).toHaveBeenCalled(); | ||
| expect(mockSentryRollupPlugin).toHaveBeenCalled(); | ||
| expect(viteConfig.plugins.length).toBeGreaterThan(0); | ||
| expect(nitroConfig.rollupConfig.plugins.length).toBeGreaterThan(0); | ||
| expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('[Sentry]')); | ||
| }); | ||
| it('should not call source map related functions in dev mode', async () => { | ||
| const { setupSourceMaps } = await import('../../src/vite/sourceMaps'); | ||
| const mockNuxt = createMockNuxt({ _prepare: false, dev: true }); | ||
| setupSourceMaps({ debug: true }, mockNuxt as unknown as Nuxt); | ||
| await mockNuxt.triggerHook('modules:done'); | ||
| await mockNuxt.triggerHook( | ||
| 'vite:extendConfig', | ||
| { build: {}, plugins: [], mode: 'development' }, | ||
| { isServer: true, isClient: false }, | ||
| ); | ||
| await mockNuxt.triggerHook('nitro:config', { rollupConfig: { plugins: [] }, dev: true }); | ||
| expect(mockSentryVitePlugin).not.toHaveBeenCalled(); | ||
| expect(mockSentryRollupPlugin).not.toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
s1gr1d marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.