From c029e2a110bdc63883dc336aa8f5799bd566f708 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 20 Oct 2025 17:43:44 +0200 Subject: [PATCH] update bundler detection --- .../test-applications/nextjs-16/package.json | 2 +- packages/nextjs/src/config/util.ts | 64 +---- .../nextjs/src/config/withSentryConfig.ts | 2 +- packages/nextjs/test/config/util.test.ts | 161 +---------- .../test/config/withSentryConfig.test.ts | 268 +++++------------- 5 files changed, 89 insertions(+), 408 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16/package.json b/dev-packages/e2e-tests/test-applications/nextjs-16/package.json index 3d1df82b1748..2da23b152807 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-16/package.json @@ -18,7 +18,7 @@ "test:build-canary": "pnpm install && pnpm add next@canary && pnpm build", "test:build-canary-webpack": "pnpm install && pnpm add next@canary && pnpm build-webpack", "test:assert": "pnpm test:prod && pnpm test:dev", - "test:assert-webpack": "pnpm test:prod" + "test:assert-webpack": "pnpm test:prod && pnpm test:dev-webpack" }, "dependencies": { "@sentry/nextjs": "latest || *", diff --git a/packages/nextjs/src/config/util.ts b/packages/nextjs/src/config/util.ts index 8d2d7781230b..0970e9573ba9 100644 --- a/packages/nextjs/src/config/util.ts +++ b/packages/nextjs/src/config/util.ts @@ -109,66 +109,20 @@ export function supportsNativeDebugIds(version: string): boolean { } /** - * Checks if the current Next.js version uses Turbopack as the default bundler. - * Starting from Next.js 15.6.0-canary.38, turbopack became the default for `next build`. + * Determines which bundler is actually being used based on environment variables, + * and CLI flags. * - * @param version - Next.js version string to check. - * @returns true if the version uses Turbopack by default + * @returns 'turbopack' or 'webpack' */ -export function isTurbopackDefaultForVersion(version: string): boolean { - if (!version) { - return false; - } - - const { major, minor, prerelease } = parseSemver(version); - - if (major === undefined || minor === undefined) { - return false; - } +export function detectActiveBundler(): 'turbopack' | 'webpack' { + const turbopackEnv = process.env.TURBOPACK; - // Next.js 16+ uses turbopack by default - if (major >= 16) { - return true; - } + // Check if TURBOPACK env var is set to a truthy value (excluding falsy strings like 'false', '0', '') + const isTurbopackEnabled = turbopackEnv && turbopackEnv !== 'false' && turbopackEnv !== '0'; - // For Next.js 15, only canary versions 15.6.0-canary.40+ use turbopack by default - // Stable 15.x releases still use webpack by default - if (major === 15 && minor >= 6 && prerelease && prerelease.startsWith('canary.')) { - if (minor >= 7) { - return true; - } - const canaryNumber = parseInt(prerelease.split('.')[1] || '0', 10); - if (canaryNumber >= 40) { - return true; - } - } - - return false; -} - -/** - * Determines which bundler is actually being used based on environment variables, - * CLI flags, and Next.js version. - * - * @param nextJsVersion - The Next.js version string - * @returns 'turbopack', 'webpack', or undefined if it cannot be determined - */ -export function detectActiveBundler(nextJsVersion: string | undefined): 'turbopack' | 'webpack' | undefined { - if (process.env.TURBOPACK || process.argv.includes('--turbo')) { + if (isTurbopackEnabled || process.argv.includes('--turbo')) { return 'turbopack'; - } - - // Explicit opt-in to webpack via --webpack flag - if (process.argv.includes('--webpack')) { + } else { return 'webpack'; } - - // Fallback to version-based default behavior - if (nextJsVersion) { - const turbopackIsDefault = isTurbopackDefaultForVersion(nextJsVersion); - return turbopackIsDefault ? 'turbopack' : 'webpack'; - } - - // Unlikely but at this point, we just assume webpack for older behavior - return 'webpack'; } diff --git a/packages/nextjs/src/config/withSentryConfig.ts b/packages/nextjs/src/config/withSentryConfig.ts index 31ea63f17a9c..1f3f14479656 100644 --- a/packages/nextjs/src/config/withSentryConfig.ts +++ b/packages/nextjs/src/config/withSentryConfig.ts @@ -261,7 +261,7 @@ function getFinalConfigObject( nextMajor = major; } - const activeBundler = detectActiveBundler(nextJsVersion); + const activeBundler = detectActiveBundler(); const isTurbopack = activeBundler === 'turbopack'; const isWebpack = activeBundler === 'webpack'; const isTurbopackSupported = supportsProductionCompileHook(nextJsVersion ?? ''); diff --git a/packages/nextjs/test/config/util.test.ts b/packages/nextjs/test/config/util.test.ts index 55fd13cf5dc4..37e4079376cd 100644 --- a/packages/nextjs/test/config/util.test.ts +++ b/packages/nextjs/test/config/util.test.ts @@ -213,117 +213,6 @@ describe('util', () => { }); }); - describe('isTurbopackDefaultForVersion', () => { - describe('returns true for versions where turbopack is default', () => { - it.each([ - // Next.js 16+ stable versions - ['16.0.0', 'Next.js 16.0.0 stable'], - ['16.0.1', 'Next.js 16.0.1 stable'], - ['16.1.0', 'Next.js 16.1.0 stable'], - ['16.2.5', 'Next.js 16.2.5 stable'], - - // Next.js 16+ pre-release versions - ['16.0.0-rc.1', 'Next.js 16.0.0-rc.1'], - ['16.0.0-canary.1', 'Next.js 16.0.0-canary.1'], - ['16.1.0-beta.2', 'Next.js 16.1.0-beta.2'], - - // Next.js 17+ - ['17.0.0', 'Next.js 17.0.0'], - ['18.0.0', 'Next.js 18.0.0'], - ['20.0.0', 'Next.js 20.0.0'], - - // Next.js 15.6.0-canary.40+ (boundary case) - ['15.6.0-canary.40', 'Next.js 15.6.0-canary.40 (exact threshold)'], - ['15.6.0-canary.41', 'Next.js 15.6.0-canary.41'], - ['15.6.0-canary.42', 'Next.js 15.6.0-canary.42'], - ['15.6.0-canary.100', 'Next.js 15.6.0-canary.100'], - - // Next.js 15.7+ canary versions - ['15.7.0-canary.1', 'Next.js 15.7.0-canary.1'], - ['15.7.0-canary.50', 'Next.js 15.7.0-canary.50'], - ['15.8.0-canary.1', 'Next.js 15.8.0-canary.1'], - ['15.10.0-canary.1', 'Next.js 15.10.0-canary.1'], - ])('returns true for %s (%s)', version => { - expect(util.isTurbopackDefaultForVersion(version)).toBe(true); - }); - }); - - describe('returns false for versions where webpack is still default', () => { - it.each([ - // Next.js 15.6.0-canary.39 and below - ['15.6.0-canary.39', 'Next.js 15.6.0-canary.39 (just below threshold)'], - ['15.6.0-canary.36', 'Next.js 15.6.0-canary.36'], - ['15.6.0-canary.38', 'Next.js 15.6.0-canary.38'], - ['15.6.0-canary.0', 'Next.js 15.6.0-canary.0'], - - // Next.js 15.6.x stable releases (NOT canary) - ['15.6.0', 'Next.js 15.6.0 stable'], - ['15.6.1', 'Next.js 15.6.1 stable'], - ['15.6.2', 'Next.js 15.6.2 stable'], - ['15.6.10', 'Next.js 15.6.10 stable'], - - // Next.js 15.6.x rc releases (NOT canary) - ['15.6.0-rc.1', 'Next.js 15.6.0-rc.1'], - ['15.6.0-rc.2', 'Next.js 15.6.0-rc.2'], - - // Next.js 15.7+ stable releases (NOT canary) - ['15.7.0', 'Next.js 15.7.0 stable'], - ['15.8.0', 'Next.js 15.8.0 stable'], - ['15.10.0', 'Next.js 15.10.0 stable'], - - // Next.js 15.5 and below (all versions) - ['15.5.0', 'Next.js 15.5.0'], - ['15.5.0-canary.100', 'Next.js 15.5.0-canary.100'], - ['15.4.1', 'Next.js 15.4.1'], - ['15.0.0', 'Next.js 15.0.0'], - ['15.0.0-canary.1', 'Next.js 15.0.0-canary.1'], - - // Next.js 14.x and below - ['14.2.0', 'Next.js 14.2.0'], - ['14.0.0', 'Next.js 14.0.0'], - ['14.0.0-canary.50', 'Next.js 14.0.0-canary.50'], - ['13.5.0', 'Next.js 13.5.0'], - ['13.0.0', 'Next.js 13.0.0'], - ['12.0.0', 'Next.js 12.0.0'], - ])('returns false for %s (%s)', version => { - expect(util.isTurbopackDefaultForVersion(version)).toBe(false); - }); - }); - - describe('edge cases', () => { - it.each([ - ['', 'empty string'], - ['invalid', 'invalid version string'], - ['15', 'missing minor and patch'], - ['15.6', 'missing patch'], - ['not.a.version', 'completely invalid'], - ['15.6.0-alpha.1', 'alpha prerelease (not canary)'], - ['15.6.0-beta.1', 'beta prerelease (not canary)'], - ])('returns false for %s (%s)', version => { - expect(util.isTurbopackDefaultForVersion(version)).toBe(false); - }); - }); - - describe('canary number parsing edge cases', () => { - it.each([ - ['15.6.0-canary.', 'canary with no number'], - ['15.6.0-canary.abc', 'canary with non-numeric value'], - ['15.6.0-canary.38.extra', 'canary with extra segments'], - ])('handles malformed canary versions: %s (%s)', version => { - // Should not throw, just return appropriate boolean - expect(() => util.isTurbopackDefaultForVersion(version)).not.toThrow(); - }); - - it('handles canary.40 exactly (boundary)', () => { - expect(util.isTurbopackDefaultForVersion('15.6.0-canary.40')).toBe(true); - }); - - it('handles canary.39 exactly (boundary)', () => { - expect(util.isTurbopackDefaultForVersion('15.6.0-canary.39')).toBe(false); - }); - }); - }); - describe('detectActiveBundler', () => { const originalArgv = process.argv; const originalEnv = process.env; @@ -341,52 +230,26 @@ describe('util', () => { it('returns turbopack when TURBOPACK env var is set', () => { process.env.TURBOPACK = '1'; - expect(util.detectActiveBundler('15.5.0')).toBe('turbopack'); - }); - - it('returns webpack when --webpack flag is present', () => { - process.argv.push('--webpack'); - expect(util.detectActiveBundler('16.0.0')).toBe('webpack'); - }); - - it('returns turbopack for Next.js 16+ by default', () => { - expect(util.detectActiveBundler('16.0.0')).toBe('turbopack'); - expect(util.detectActiveBundler('17.0.0')).toBe('turbopack'); - }); - - it('returns turbopack for Next.js 15.6.0-canary.40+', () => { - expect(util.detectActiveBundler('15.6.0-canary.40')).toBe('turbopack'); - expect(util.detectActiveBundler('15.6.0-canary.50')).toBe('turbopack'); + expect(util.detectActiveBundler()).toBe('turbopack'); }); - it('returns webpack for Next.js 15.6.0 stable', () => { - expect(util.detectActiveBundler('15.6.0')).toBe('webpack'); + it('returns turbopack when TURBOPACK env var is set to auto', () => { + process.env.TURBOPACK = 'auto'; + expect(util.detectActiveBundler()).toBe('turbopack'); }); - it('returns webpack for Next.js 15.5.x and below', () => { - expect(util.detectActiveBundler('15.5.0')).toBe('webpack'); - expect(util.detectActiveBundler('15.0.0')).toBe('webpack'); - expect(util.detectActiveBundler('14.2.0')).toBe('webpack'); + it('returns webpack when TURBOPACK env var is undefined', () => { + process.env.TURBOPACK = undefined; + expect(util.detectActiveBundler()).toBe('webpack'); }); - it('returns webpack when version is undefined', () => { - expect(util.detectActiveBundler(undefined)).toBe('webpack'); + it('returns webpack when TURBOPACK env var is false', () => { + process.env.TURBOPACK = 'false'; + expect(util.detectActiveBundler()).toBe('webpack'); }); - it('prioritizes TURBOPACK env var over version detection', () => { - process.env.TURBOPACK = '1'; - expect(util.detectActiveBundler('14.0.0')).toBe('turbopack'); - }); - - it('prioritizes --webpack flag over version detection', () => { - process.argv.push('--webpack'); - expect(util.detectActiveBundler('16.0.0')).toBe('webpack'); - }); - - it('prioritizes TURBOPACK env var over --webpack flag', () => { - process.env.TURBOPACK = '1'; - process.argv.push('--webpack'); - expect(util.detectActiveBundler('15.5.0')).toBe('turbopack'); + it('returns webpack when TURBOPACK env var is not set', () => { + expect(util.detectActiveBundler()).toBe('webpack'); }); }); }); diff --git a/packages/nextjs/test/config/withSentryConfig.test.ts b/packages/nextjs/test/config/withSentryConfig.test.ts index f1f46c6fc6f2..b67a05845a7e 100644 --- a/packages/nextjs/test/config/withSentryConfig.test.ts +++ b/packages/nextjs/test/config/withSentryConfig.test.ts @@ -269,7 +269,7 @@ describe('withSentryConfig', () => { }); }); - describe('bundler detection with version-based defaults', () => { + describe('bundler detection', () => { const originalTurbopack = process.env.TURBOPACK; const originalArgv = process.argv; @@ -284,192 +284,107 @@ describe('withSentryConfig', () => { process.argv = originalArgv; }); - describe('Next.js 16+ defaults to turbopack', () => { - it('uses turbopack config by default for Next.js 16.0.0', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('16.0.0'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); - - it('uses turbopack config by default for Next.js 17.0.0', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('17.0.0'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); - - it('uses webpack when --webpack flag is present on Next.js 16.0.0', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('16.0.0'); - process.argv.push('--webpack'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); - - it('prioritizes TURBOPACK env var over --webpack flag', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('16.0.0'); - process.env.TURBOPACK = '1'; - process.argv.push('--webpack'); + it('uses webpack config by default when TURBOPACK env var is not set', () => { + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('16.0.0'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); + expect(finalConfig.turbopack).toBeUndefined(); + expect(finalConfig.webpack).toBeInstanceOf(Function); }); - describe('Next.js 15.6.0-canary.40+ defaults to turbopack', () => { - it('uses turbopack config by default for 15.6.0-canary.40', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.40'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); - - it('uses turbopack config by default for 15.6.0-canary.50', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.50'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); - - it('uses turbopack config by default for 15.7.0-canary.1', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.7.0-canary.1'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); - - it('uses webpack when --webpack flag is present on 15.6.0-canary.40', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.40'); - process.argv.push('--webpack'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); - - it('uses webpack when --webpack flag is present on 15.7.0-canary.1', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.7.0-canary.1'); - process.argv.push('--webpack'); + it('uses turbopack config when TURBOPACK env var is set (supported version)', () => { + process.env.TURBOPACK = '1'; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.4.1'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + expect(finalConfig.turbopack).toBeDefined(); + expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); }); - describe('Next.js 15.6.0-canary.37 and below defaults to webpack', () => { - it('uses webpack config by default for 15.6.0-canary.37', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.37'); + it('uses turbopack config when TURBOPACK env var is set (16.0.0)', () => { + process.env.TURBOPACK = '1'; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('16.0.0'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + expect(finalConfig.turbopack).toBeDefined(); + expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); + }); - it('uses webpack config by default for 15.6.0-canary.1', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.1'); + it('skips webpack config when TURBOPACK env var is set, even with unsupported version', () => { + process.env.TURBOPACK = '1'; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.0.0'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + // turbopack config won't be added when version is unsupported, + // but webpack config should still be skipped + expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); + expect(finalConfig.turbopack).toBeUndefined(); + }); - it('uses turbopack when TURBOPACK env var is set on 15.6.0-canary.37', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0-canary.37'); - process.env.TURBOPACK = '1'; + it('defaults to webpack when Next.js version cannot be determined and no TURBOPACK env var', () => { + vi.spyOn(util, 'getNextjsVersion').mockReturnValue(undefined); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); + expect(finalConfig.turbopack).toBeUndefined(); + expect(finalConfig.webpack).toBeInstanceOf(Function); }); - describe('Next.js 15.6.x stable releases default to webpack', () => { - it('uses webpack config by default for 15.6.0 stable', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + it('uses turbopack when TURBOPACK env var is set even when version is undefined', () => { + vi.spyOn(util, 'getNextjsVersion').mockReturnValue(undefined); + process.env.TURBOPACK = '1'; - it('uses webpack config by default for 15.6.1 stable', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.1'); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + expect(finalConfig.turbopack).toBeUndefined(); + }); - it('uses webpack config by default for 15.7.0 stable', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.7.0'); + it('uses turbopack when TURBOPACK env var is truthy string', () => { + process.env.TURBOPACK = 'true'; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.4.1'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); + expect(finalConfig.turbopack).toBeDefined(); + expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); + }); - it('uses turbopack when explicitly requested via env var on 15.6.0 stable', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.6.0'); - process.env.TURBOPACK = '1'; + it('uses webpack when TURBOPACK env var is empty string', () => { + process.env.TURBOPACK = ''; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.4.1'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeDefined(); - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - }); + expect(finalConfig.turbopack).toBeUndefined(); + expect(finalConfig.webpack).toBeInstanceOf(Function); }); - describe('older Next.js versions default to webpack', () => { - it.each([['15.5.0'], ['15.0.0'], ['14.2.0'], ['13.5.0']])( - 'uses webpack config by default for Next.js %s', - version => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue(version); + it('uses webpack when TURBOPACK env var is false string', () => { + process.env.TURBOPACK = 'false'; + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.4.1'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }, - ); + expect(finalConfig.turbopack).toBeUndefined(); + expect(finalConfig.webpack).toBeInstanceOf(Function); + }); - it.each([['15.5.0-canary.100'], ['15.0.0-canary.1'], ['14.2.0-canary.50']])( - 'uses webpack config by default for Next.js %s canary', - version => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue(version); + it('handles malformed version strings gracefully', () => { + vi.spyOn(util, 'getNextjsVersion').mockReturnValue('not.a.version'); - const finalConfig = materializeFinalNextConfig(exportedNextConfig); + const finalConfig = materializeFinalNextConfig(exportedNextConfig); - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }, - ); + expect(finalConfig.turbopack).toBeUndefined(); + expect(finalConfig.webpack).toBeInstanceOf(Function); }); - describe('warnings are shown for unsupported turbopack usage', () => { + describe('warnings for unsupported turbopack usage', () => { let consoleWarnSpy: ReturnType; beforeEach(() => { @@ -508,39 +423,6 @@ describe('withSentryConfig', () => { expect(consoleWarnSpy).not.toHaveBeenCalled(); }); }); - - describe('edge cases', () => { - it('defaults to webpack when Next.js version cannot be determined', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue(undefined); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); - - it('uses turbopack when TURBOPACK env var is set even when version is undefined', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue(undefined); - process.env.TURBOPACK = '1'; - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - // Note: turbopack config won't be added when version is undefined because - // isTurbopackSupported will be false, but webpack config should still be skipped - expect(finalConfig.webpack).toBe(exportedNextConfig.webpack); - // Turbopack config is only added when both isTurbopack AND isTurbopackSupported are true - expect(finalConfig.turbopack).toBeUndefined(); - }); - - it('handles malformed version strings gracefully', () => { - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('not.a.version'); - - const finalConfig = materializeFinalNextConfig(exportedNextConfig); - - expect(finalConfig.turbopack).toBeUndefined(); - expect(finalConfig.webpack).toBeInstanceOf(Function); - }); - }); }); describe('turbopack sourcemap configuration', () => { @@ -1411,24 +1293,6 @@ describe('withSentryConfig', () => { consoleWarnSpy.mockRestore(); }); - - it('warns when TURBOPACK=0 (truthy string) with unsupported version', () => { - process.env.TURBOPACK = '0'; - // @ts-expect-error - NODE_ENV is read-only in types but we need to set it for testing - process.env.NODE_ENV = 'development'; - vi.spyOn(util, 'getNextjsVersion').mockReturnValue('15.4.1'); - vi.spyOn(util, 'supportsProductionCompileHook').mockReturnValue(false); - const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); - - materializeFinalNextConfig(exportedNextConfig); - - // Note: '0' is truthy in JavaScript, so this will trigger the warning - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringContaining('WARNING: You are using the Sentry SDK with Turbopack'), - ); - - consoleWarnSpy.mockRestore(); - }); }); describe('useRunAfterProductionCompileHook warning logic', () => {