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
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
"private": true,
"scripts": {
"build": "next build > .tmp_build_stdout 2> .tmp_build_stderr || (cat .tmp_build_stdout && cat .tmp_build_stderr && exit 1)",
"build:webpack": "next build --webpack > .tmp_build_stdout 2> .tmp_build_stderr || (cat .tmp_build_stdout && cat .tmp_build_stderr && exit 1)",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:prod": "TEST_ENV=production playwright test",
"test:dev": "TEST_ENV=development playwright test",
"test:dev-webpack": "TEST_ENV=development-webpack playwright test",
"test:build": "pnpm install && pnpm build",
"test:test-build": "pnpm ts-node --script-mode assert-build.ts",
"test:build-canary": "pnpm install && pnpm add next@canary && pnpm add react@beta && pnpm add react-dom@beta && pnpm build",
"test:build-canary": "pnpm install && pnpm add next@canary && pnpm add react@latest && pnpm add react-dom@latest && pnpm build:webpack",
"test:build-latest": "pnpm install && pnpm add next@latest && pnpm build",
"test:build-13": "pnpm install && pnpm add [email protected] && pnpm build",
"test:assert": "pnpm test:test-build && pnpm test:prod && pnpm test:dev"
Expand Down Expand Up @@ -43,7 +45,8 @@
"optionalVariants": [
{
"build-command": "pnpm test:build-canary",
"label": "nextjs-app-dir (canary)"
"label": "nextjs-app-dir (canary, webpack opt-in)",
"assert-command": "pnpm test:prod && pnpm test:dev-webpack"
},
{
"build-command": "pnpm test:build-latest",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ if (!testEnv) {
throw new Error('No test env defined');
}

const getStartCommand = () => {
if (testEnv === 'development-webpack') {
return 'pnpm next dev -p 3030 --webpack';
}

return testEnv === 'development' ? 'pnpm next dev -p 3030' : 'pnpm next start -p 3030';
};

const config = getPlaywrightConfig({
startCommand: testEnv === 'development' ? 'pnpm next dev -p 3030' : 'pnpm next start -p 3030',
startCommand: getStartCommand(),
port: 3030,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
"private": true,
"scripts": {
"build": "next build > .tmp_build_stdout 2> .tmp_build_stderr || (cat .tmp_build_stdout && cat .tmp_build_stderr && exit 1)",
"build:webpack": "next build --webpack > .tmp_build_stdout 2> .tmp_build_stderr || (cat .tmp_build_stdout && cat .tmp_build_stderr && exit 1)",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:prod": "TEST_ENV=production playwright test",
"test:dev": "TEST_ENV=development playwright test",
"test:dev-webpack": "TEST_ENV=development-webpack playwright test",
"test:build": "pnpm install && pnpm build",
"test:test-build": "pnpm ts-node --script-mode assert-build.ts",
"test:build-canary": "pnpm install && pnpm add next@canary && pnpm add react@beta && pnpm add react-dom@beta && pnpm build",
"test:build-canary": "pnpm install && pnpm add next@canary && pnpm add react@latest && pnpm add react-dom@latest && pnpm build:webpack",
"test:build-latest": "pnpm install && pnpm add next@latest && pnpm add react@latest && pnpm add react-dom@latest && pnpm build",
"test:build-13": "pnpm install && pnpm add [email protected] && pnpm build",
"test:assert": "pnpm test:test-build && pnpm test:prod && pnpm test:dev"
Expand Down Expand Up @@ -43,7 +45,8 @@
"optionalVariants": [
{
"build-command": "pnpm test:build-canary",
"label": "nextjs-pages-dir (canary)"
"label": "nextjs-pages-dir (canary, webpack opt-in)",
"assert-command": "pnpm test:prod && pnpm test:dev-webpack"
},
{
"build-command": "pnpm test:build-latest",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ if (!testEnv) {
throw new Error('No test env defined');
}

const getStartCommand = () => {
if (testEnv === 'development-webpack') {
return 'pnpm next dev -p 3030 --webpack';
}

return testEnv === 'development' ? 'pnpm next dev -p 3030' : 'pnpm next start -p 3030';
};

const config = getPlaywrightConfig({
startCommand: testEnv === 'development' ? 'pnpm next dev -p 3030' : 'pnpm next start -p 3030',
startCommand: getStartCommand(),
port: 3030,
});

Expand Down
65 changes: 65 additions & 0 deletions packages/nextjs/src/config/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,68 @@ export function supportsProductionCompileHook(version: string): boolean {

return false;
}

/**
* 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`.
*
* @param version - Next.js version string to check.
* @returns true if the version uses Turbopack by default
*/
export function isTurbopackDefaultForVersion(version: string): boolean {
if (!version) {
return false;
}

const { major, minor, prerelease } = parseSemver(version);

if (major === undefined || minor === undefined) {
return false;
}

// Next.js 16+ uses turbopack by default
if (major >= 16) {
return true;
}

// 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')) {
return 'turbopack';
}

// Explicit opt-in to webpack via --webpack flag
if (process.argv.includes('--webpack')) {
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';
}
35 changes: 16 additions & 19 deletions packages/nextjs/src/config/withSentryConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
NextConfigObject,
SentryBuildOptions,
} from './types';
import { getNextjsVersion, supportsProductionCompileHook } from './util';
import { detectActiveBundler, getNextjsVersion, supportsProductionCompileHook } from './util';
import { constructWebpackConfigFunction } from './webpack';

let showedExportModeTunnelWarning = false;
Expand Down Expand Up @@ -258,28 +258,24 @@ function getFinalConfigObject(
nextMajor = major;
}

const isTurbopack = process.env.TURBOPACK;
const activeBundler = detectActiveBundler(nextJsVersion);
const isTurbopack = activeBundler === 'turbopack';
const isWebpack = activeBundler === 'webpack';
const isTurbopackSupported = supportsProductionCompileHook(nextJsVersion ?? '');

// Warn if using turbopack with an unsupported Next.js version
if (!isTurbopackSupported && isTurbopack) {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn(
`[@sentry/nextjs] WARNING: You are using the Sentry SDK with Turbopack (\`next dev --turbopack\`). The Sentry SDK is compatible with Turbopack on Next.js version 15.4.1 or later. You are currently on ${nextJsVersion}. Please upgrade to a newer Next.js version to use the Sentry SDK with Turbopack.`,
);
} else if (process.env.NODE_ENV === 'production') {
// eslint-disable-next-line no-console
console.warn(
`[@sentry/nextjs] WARNING: You are using the Sentry SDK with Turbopack (\`next build --turbopack\`). The Sentry SDK is compatible with Turbopack on Next.js version 15.4.1 or later. You are currently on ${nextJsVersion}. Please upgrade to a newer Next.js version to use the Sentry SDK with Turbopack.`,
);
}
// eslint-disable-next-line no-console
console.warn(
`[@sentry/nextjs] WARNING: You are using the Sentry SDK with Turbopack. The Sentry SDK is compatible with Turbopack on Next.js version 15.4.1 or later. You are currently on ${nextJsVersion}. Please upgrade to a newer Next.js version to use the Sentry SDK with Turbopack.`,
);
}

// webpack case
// Webpack case - warn if trying to use runAfterProductionCompile hook with unsupported Next.js version
if (
userSentryOptions.useRunAfterProductionCompileHook &&
!supportsProductionCompileHook(nextJsVersion ?? '') &&
!isTurbopack
isWebpack
) {
// eslint-disable-next-line no-console
console.warn(
Expand Down Expand Up @@ -367,17 +363,18 @@ function getFinalConfigObject(
],
},
}),
webpack:
isTurbopack || userSentryOptions.disableSentryWebpackConfig
? incomingUserNextConfigObject.webpack // just return the original webpack config
: constructWebpackConfigFunction({
...(isWebpack && !userSentryOptions.disableSentryWebpackConfig
? {
webpack: constructWebpackConfigFunction({
userNextConfig: incomingUserNextConfigObject,
userSentryOptions,
releaseName,
routeManifest,
nextJsVersion,
useRunAfterProductionCompileHook: shouldUseRunAfterProductionCompileHook,
}),
}
: {}),
...(isTurbopackSupported && isTurbopack
? {
turbopack: constructTurbopackConfig({
Expand Down
Loading
Loading