Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
283 lines
9.2 KiB
Plaintext
283 lines
9.2 KiB
Plaintext
import { handleRunAfterProductionCompile } from '../handleRunAfterProductionCompile.js';
|
|
import { constructTurbopackConfig } from '../turbopack/constructTurbopackConfig.js';
|
|
import { detectActiveBundler, supportsProductionCompileHook } from '../util.js';
|
|
import { constructWebpackConfigFunction } from '../webpack.js';
|
|
import { DEFAULT_SERVER_EXTERNAL_PACKAGES } from './constants.js';
|
|
|
|
/**
|
|
* Information about the active bundler and feature support based on Next.js version.
|
|
*/
|
|
|
|
/**
|
|
* Detects which bundler is active (webpack vs turbopack) and whether turbopack features are supported.
|
|
*/
|
|
function getBundlerInfo(nextJsVersion) {
|
|
const activeBundler = detectActiveBundler();
|
|
const isTurbopack = activeBundler === 'turbopack';
|
|
const isWebpack = activeBundler === 'webpack';
|
|
const isTurbopackSupported = supportsProductionCompileHook(nextJsVersion ?? '');
|
|
|
|
return { isTurbopack, isWebpack, isTurbopackSupported };
|
|
}
|
|
|
|
/**
|
|
* Warns if turbopack is in use but the detected Next.js version is unsupported.
|
|
*/
|
|
function maybeWarnAboutUnsupportedTurbopack(nextJsVersion, bundlerInfo) {
|
|
// Warn if using turbopack with an unsupported Next.js version
|
|
if (!bundlerInfo.isTurbopackSupported && bundlerInfo.isTurbopack) {
|
|
// 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.`,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Warns if `useRunAfterProductionCompileHook` is enabled in webpack mode but the Next.js version is unsupported.
|
|
*/
|
|
function maybeWarnAboutUnsupportedRunAfterProductionCompileHook(
|
|
nextJsVersion,
|
|
userSentryOptions,
|
|
bundlerInfo,
|
|
) {
|
|
// Webpack case - warn if trying to use runAfterProductionCompile hook with unsupported Next.js version
|
|
if (
|
|
userSentryOptions.useRunAfterProductionCompileHook &&
|
|
!supportsProductionCompileHook(nextJsVersion ?? '') &&
|
|
bundlerInfo.isWebpack
|
|
) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn(
|
|
'[@sentry/nextjs] The configured `useRunAfterProductionCompileHook` option is not compatible with your current Next.js version. This option is only supported on Next.js version 15.4.1 or later. Will not run source map and release management logic.',
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructs turbopack config when turbopack is active.
|
|
*/
|
|
function maybeConstructTurbopackConfig(
|
|
incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
routeManifest,
|
|
nextJsVersion,
|
|
bundlerInfo,
|
|
vercelCronsConfigResult,
|
|
) {
|
|
if (!bundlerInfo.isTurbopack) {
|
|
return undefined;
|
|
}
|
|
|
|
// Only pass crons config if the span-based approach is enabled
|
|
const vercelCronsConfig = vercelCronsConfigResult.strategy === 'spans' ? vercelCronsConfigResult.config : undefined;
|
|
|
|
return constructTurbopackConfig({
|
|
userNextConfig: incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
routeManifest,
|
|
nextJsVersion,
|
|
vercelCronsConfig,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Resolves whether to use the `runAfterProductionCompile` hook based on options and bundler.
|
|
*/
|
|
function resolveUseRunAfterProductionCompileHookOption(
|
|
userSentryOptions,
|
|
bundlerInfo,
|
|
) {
|
|
// If not explicitly set, turbopack uses the runAfterProductionCompile hook (as there are no alternatives), webpack does not.
|
|
return userSentryOptions.useRunAfterProductionCompileHook ?? (bundlerInfo.isTurbopack ? true : false);
|
|
}
|
|
|
|
/**
|
|
* Hooks into Next.js' `compiler.runAfterProductionCompile` to run Sentry release/sourcemap handling.
|
|
*
|
|
* Note: this mutates `incomingUserNextConfigObject`.
|
|
*/
|
|
function maybeSetUpRunAfterProductionCompileHook({
|
|
incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
releaseName,
|
|
nextJsVersion,
|
|
bundlerInfo,
|
|
turboPackConfig,
|
|
shouldUseRunAfterProductionCompileHook,
|
|
}
|
|
|
|
) {
|
|
if (!shouldUseRunAfterProductionCompileHook) {
|
|
return;
|
|
}
|
|
|
|
if (!supportsProductionCompileHook(nextJsVersion ?? '')) {
|
|
return;
|
|
}
|
|
|
|
if (incomingUserNextConfigObject?.compiler?.runAfterProductionCompile === undefined) {
|
|
incomingUserNextConfigObject.compiler ??= {};
|
|
|
|
incomingUserNextConfigObject.compiler.runAfterProductionCompile = async ({ distDir }) => {
|
|
await handleRunAfterProductionCompile(
|
|
{
|
|
releaseName,
|
|
distDir,
|
|
buildTool: bundlerInfo.isTurbopack ? 'turbopack' : 'webpack',
|
|
usesNativeDebugIds: bundlerInfo.isTurbopack ? turboPackConfig?.debugIds : undefined,
|
|
},
|
|
userSentryOptions,
|
|
);
|
|
};
|
|
return;
|
|
}
|
|
|
|
if (typeof incomingUserNextConfigObject.compiler.runAfterProductionCompile === 'function') {
|
|
incomingUserNextConfigObject.compiler.runAfterProductionCompile = new Proxy(
|
|
incomingUserNextConfigObject.compiler.runAfterProductionCompile,
|
|
{
|
|
async apply(target, thisArg, argArray) {
|
|
const { distDir } = argArray[0] ?? { distDir: '.next' };
|
|
await target.apply(thisArg, argArray);
|
|
await handleRunAfterProductionCompile(
|
|
{
|
|
releaseName,
|
|
distDir,
|
|
buildTool: bundlerInfo.isTurbopack ? 'turbopack' : 'webpack',
|
|
usesNativeDebugIds: bundlerInfo.isTurbopack ? turboPackConfig?.debugIds : undefined,
|
|
},
|
|
userSentryOptions,
|
|
);
|
|
},
|
|
},
|
|
);
|
|
return;
|
|
}
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.warn(
|
|
'[@sentry/nextjs] The configured `compiler.runAfterProductionCompile` option is not a function. Will not run source map and release management logic.',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* For supported turbopack builds, auto-enables browser sourcemaps and defaults to deleting them after upload.
|
|
*
|
|
* Note: this mutates both `incomingUserNextConfigObject` and `userSentryOptions`.
|
|
*/
|
|
function maybeEnableTurbopackSourcemaps(
|
|
incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
bundlerInfo,
|
|
) {
|
|
// Enable source maps for turbopack builds
|
|
if (!bundlerInfo.isTurbopackSupported || !bundlerInfo.isTurbopack || userSentryOptions.sourcemaps?.disable) {
|
|
return;
|
|
}
|
|
|
|
// Only set if not already configured by user
|
|
if (incomingUserNextConfigObject.productionBrowserSourceMaps !== undefined) {
|
|
return;
|
|
}
|
|
|
|
if (userSentryOptions.debug) {
|
|
// eslint-disable-next-line no-console
|
|
console.log('[@sentry/nextjs] Automatically enabling browser source map generation for turbopack build.');
|
|
}
|
|
incomingUserNextConfigObject.productionBrowserSourceMaps = true;
|
|
|
|
// Enable source map deletion if not explicitly disabled
|
|
if (userSentryOptions.sourcemaps?.deleteSourcemapsAfterUpload !== undefined) {
|
|
return;
|
|
}
|
|
|
|
if (userSentryOptions.debug) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn(
|
|
'[@sentry/nextjs] Source maps will be automatically deleted after being uploaded to Sentry. If you want to keep the source maps, set the `sourcemaps.deleteSourcemapsAfterUpload` option to false in `withSentryConfig()`. If you do not want to generate and upload sourcemaps at all, set the `sourcemaps.disable` option to true.',
|
|
);
|
|
}
|
|
|
|
userSentryOptions.sourcemaps = {
|
|
...userSentryOptions.sourcemaps,
|
|
deleteSourcemapsAfterUpload: true,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns the patch which ensures server-side auto-instrumented packages are externalized.
|
|
*/
|
|
function getServerExternalPackagesPatch(
|
|
incomingUserNextConfigObject,
|
|
nextMajor,
|
|
) {
|
|
if (nextMajor && nextMajor >= 15) {
|
|
return {
|
|
serverExternalPackages: [
|
|
...(incomingUserNextConfigObject.serverExternalPackages || []),
|
|
...DEFAULT_SERVER_EXTERNAL_PACKAGES,
|
|
],
|
|
};
|
|
}
|
|
|
|
return {
|
|
experimental: {
|
|
...incomingUserNextConfigObject.experimental,
|
|
serverComponentsExternalPackages: [
|
|
...(incomingUserNextConfigObject.experimental?.serverComponentsExternalPackages || []),
|
|
...DEFAULT_SERVER_EXTERNAL_PACKAGES,
|
|
],
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns the patch for injecting Sentry's webpack config function (if enabled and applicable).
|
|
*/
|
|
function getWebpackPatch({
|
|
incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
releaseName,
|
|
routeManifest,
|
|
nextJsVersion,
|
|
shouldUseRunAfterProductionCompileHook,
|
|
bundlerInfo,
|
|
vercelCronsConfigResult,
|
|
}
|
|
|
|
) {
|
|
if (!bundlerInfo.isWebpack || userSentryOptions.webpack?.disableSentryConfig) {
|
|
return {};
|
|
}
|
|
|
|
return {
|
|
webpack: constructWebpackConfigFunction({
|
|
userNextConfig: incomingUserNextConfigObject,
|
|
userSentryOptions,
|
|
releaseName,
|
|
routeManifest,
|
|
nextJsVersion,
|
|
useRunAfterProductionCompileHook: shouldUseRunAfterProductionCompileHook,
|
|
vercelCronsConfigResult,
|
|
}),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns the patch for adding turbopack config (if enabled and supported).
|
|
*/
|
|
function getTurbopackPatch(
|
|
bundlerInfo,
|
|
turboPackConfig,
|
|
) {
|
|
if (!bundlerInfo.isTurbopackSupported || !bundlerInfo.isTurbopack) {
|
|
return {};
|
|
}
|
|
|
|
return { turbopack: turboPackConfig };
|
|
}
|
|
|
|
export { getBundlerInfo, getServerExternalPackagesPatch, getTurbopackPatch, getWebpackPatch, maybeConstructTurbopackConfig, maybeEnableTurbopackSourcemaps, maybeSetUpRunAfterProductionCompileHook, maybeWarnAboutUnsupportedRunAfterProductionCompileHook, maybeWarnAboutUnsupportedTurbopack, resolveUseRunAfterProductionCompileHookOption };
|
|
//# sourceMappingURL=getFinalConfigObjectBundlerUtils.js.map
|