From fbea9d5f83b82b2559f22262c09ea85f9a983feb Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 28 Feb 2024 11:01:10 +0000 Subject: [PATCH 1/4] ref(nextjs): Remove `sentry` field in Next.js config as a means of configuration --- MIGRATION.md | 41 +++++++++++++++ packages/nextjs/src/config/types.ts | 20 ++----- .../nextjs/src/config/withSentryConfig.ts | 52 +++++++++---------- 3 files changed, 69 insertions(+), 44 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 4b44177ec71d..9f0af52714bb 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -132,6 +132,47 @@ Integrations that are now exported from `@sentry/node` and `@sentry/browser` (or - sessionTimingIntegration - dedupeIntegration (enabled by default, not pluggable) +## Next.js SDK Changes + +### Removal of the `sentry` property in your Next.js options + +With version 8 of the Sentry Next.js SDK, the SDK will no longer support passing Next.js options with a `sentry` +property to `withSentryConfig`. Please use the third argument of `withSentryConfig` to configure the SDK instead: + +```ts +// OLD +const nextConfig = { + // Your Next.js options... + + sentry: { + // Your Sentry SDK options... + }, +}; + +module.exports = withSentryConfig(nextConfig, { + // Your Sentry Webpack Plugin Options... +}); + +// NEW +const nextConfig = { + // Your Next.js options... +}; + +module.exports = withSentryConfig( + nextConfig, + { + // Your Sentry Webpack Plugin Options... + }, + { + // Your Sentry SDK options... + }, +); +``` + +The reason for this change is to have one consistent way of defining the SDK options. We hope that this change will +reduce confusion when setting up the SDK, with the upside that the explicit option is properly typed and will therefore +have code completion. + # Deprecations in 7.x You can use the **Experimental** [@sentry/migr8](https://www.npmjs.com/package/@sentry/migr8) to automatically update diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index c74990cb6a69..6c0c7c7f5526 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -4,29 +4,15 @@ import type { DefinePlugin, WebpackPluginInstance } from 'webpack'; export type SentryWebpackPluginOptions = SentryCliPluginOptions; export type SentryWebpackPlugin = WebpackPluginInstance & { options: SentryWebpackPluginOptions }; + // Export this from here because importing something from Webpack (the library) in `webpack.ts` confuses the heck out of // madge, which we use for circular dependency checking. We've manually excluded this file from the check (which is // safe, since it only includes types), so we can import it here without causing madge to fail. See // https://github.com/pahen/madge/issues/306. export type { WebpackPluginInstance }; -/** - * Overall Nextjs config - */ - -// The first argument to `withSentryConfig` (which is the user's next config) may contain a `sentry` key, which we'll -// remove once we've captured it, in order to prevent nextjs from throwing warnings. Since it's only in there -// temporarily, we don't include it in the main `NextConfigObject` or `NextConfigFunction` types. -export type ExportedNextConfig = NextConfigObjectWithSentry | NextConfigFunctionWithSentry; - -export type NextConfigObjectWithSentry = NextConfigObject & { - sentry?: UserSentryOptions; -}; - -export type NextConfigFunctionWithSentry = ( - phase: string, - defaults: { defaultConfig: NextConfigObject }, -) => NextConfigObjectWithSentry | PromiseLike; +// The first argument to `withSentryConfig` (which is the user's next config). +export type ExportedNextConfig = NextConfigObject | NextConfigFunction; // Vendored from Next.js (this type is not complete - extend if necessary) type NextRewrite = { diff --git a/packages/nextjs/src/config/withSentryConfig.ts b/packages/nextjs/src/config/withSentryConfig.ts index a665aa892c8c..6a9fae6f3a79 100644 --- a/packages/nextjs/src/config/withSentryConfig.ts +++ b/packages/nextjs/src/config/withSentryConfig.ts @@ -1,10 +1,9 @@ import { isThenable } from '@sentry/utils'; import type { - ExportedNextConfig, + ExportedNextConfig as NextConfig, NextConfigFunction, NextConfigObject, - NextConfigObjectWithSentry, SentryWebpackPluginOptions, UserSentryOptions, } from './types'; @@ -13,52 +12,51 @@ import { constructWebpackConfigFunction } from './webpack'; let showedExportModeTunnelWarning = false; /** - * Add Sentry options to the config to be exported from the user's `next.config.js` file. + * Modifies the passed in Next.js configuration * - * @param exportedUserNextConfig The existing config to be exported prior to adding Sentry - * @param userSentryWebpackPluginOptions Configuration for SentryWebpackPlugin - * @param sentryOptions Optional additional options to add as alternative to `sentry` property of config + * @param nextConfig The existing config to be exported prior to adding Sentry + * @param sentryWebpackPluginOptions Configuration for SentryWebpackPlugin + * @param sentrySDKOptions Optional additional options to add as alternative to `sentry` property of config * @returns The modified config to be exported */ export function withSentryConfig( - exportedUserNextConfig: ExportedNextConfig = {}, - userSentryWebpackPluginOptions: Partial = {}, - sentryOptions?: UserSentryOptions, + nextConfig: NextConfig = {}, + sentryWebpackPluginOptions: Partial = {}, + sentrySDKOptions: UserSentryOptions = {}, ): NextConfigFunction | NextConfigObject { - if (typeof exportedUserNextConfig === 'function') { + if (typeof nextConfig === 'function') { return function (this: unknown, ...webpackConfigFunctionArgs: unknown[]): ReturnType { - const maybeUserNextConfigObject: NextConfigObjectWithSentry = exportedUserNextConfig.apply( - this, - webpackConfigFunctionArgs, - ); + const maybePromiseNextConfig: ReturnType = nextConfig.apply(this, webpackConfigFunctionArgs); - if (isThenable(maybeUserNextConfigObject)) { - return maybeUserNextConfigObject.then(function (userNextConfigObject: NextConfigObjectWithSentry) { - const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; - return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); + if (isThenable(maybePromiseNextConfig)) { + return maybePromiseNextConfig.then(promiseResultNextConfig => { + return getFinalConfigObject(promiseResultNextConfig, sentrySDKOptions, sentryWebpackPluginOptions); }); } - // Reassign for naming-consistency sake. - const userNextConfigObject = maybeUserNextConfigObject; - const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; - return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); + return getFinalConfigObject(maybePromiseNextConfig, sentrySDKOptions, sentryWebpackPluginOptions); }; } else { - const userSentryOptions = { ...exportedUserNextConfig.sentry, ...sentryOptions }; - return getFinalConfigObject(exportedUserNextConfig, userSentryOptions, userSentryWebpackPluginOptions); + return getFinalConfigObject(nextConfig, sentrySDKOptions, sentryWebpackPluginOptions); } } // Modify the materialized object form of the user's next config by deleting the `sentry` property and wrapping the // `webpack` property function getFinalConfigObject( - incomingUserNextConfigObject: NextConfigObjectWithSentry, + incomingUserNextConfigObject: NextConfigObject, userSentryOptions: UserSentryOptions, userSentryWebpackPluginOptions: Partial, ): NextConfigObject { - // Next 12.2.3+ warns about non-canonical properties on `userNextConfig`. - delete incomingUserNextConfigObject.sentry; + if ('sentry' in incomingUserNextConfigObject) { + // eslint-disable-next-line no-console + console.warn( + '[@sentry/nextjs] Setting a `sentry` property on the Next.js config is no longer supported. Please use the `sentrySDKOptions` argument of `withSentryConfig` instead.', + ); + + // Next 12.2.3+ warns about non-canonical properties on `userNextConfig`. + delete incomingUserNextConfigObject.sentry; + } if (userSentryOptions?.tunnelRoute) { if (incomingUserNextConfigObject.output === 'export') { From 5891e4d2d53ba29f72a18d8aa9dc81c2aec088f5 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 28 Feb 2024 12:46:41 +0000 Subject: [PATCH 2/4] tests n stuff --- packages/nextjs/src/config/types.ts | 2 +- packages/nextjs/src/config/webpack.ts | 14 ++++---- .../nextjs/src/config/withSentryConfig.ts | 20 +++++------ packages/nextjs/test/config/fixtures.ts | 3 +- packages/nextjs/test/config/testUtils.ts | 11 +++--- .../webpack/constructWebpackConfig.test.ts | 34 ++++++++++--------- .../webpack/sentryWebpackPlugin.test.ts | 15 +++++--- .../test/config/withSentryConfig.test.ts | 10 ------ 8 files changed, 52 insertions(+), 57 deletions(-) diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index 6c0c7c7f5526..751969f17529 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -48,7 +48,7 @@ export type NextConfigObject = { >; }; -export type UserSentryOptions = { +export type SentryBuildtimeOptions = { /** * Override the SDK's default decision about whether or not to enable to the Sentry webpack plugin for server files. * Note that `false` forces the plugin to be enabled, even in situations where it's not recommended. diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index a6555c3b3343..5c0c57e7251c 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -18,7 +18,7 @@ import type { EntryPropertyObject, NextConfigObject, SentryWebpackPluginOptions, - UserSentryOptions, + SentryBuildtimeOptions, WebpackConfigFunction, WebpackConfigObject, WebpackConfigObjectWithModuleRules, @@ -61,7 +61,7 @@ let showedMissingGlobalErrorWarningMsg = false; export function constructWebpackConfigFunction( userNextConfig: NextConfigObject = {}, userSentryWebpackPluginOptions: Partial = {}, - userSentryOptions: UserSentryOptions = {}, + userSentryOptions: SentryBuildtimeOptions = {}, ): WebpackConfigFunction { // Will be called by nextjs and passed its default webpack configuration and context data about the build (whether // we're building server or client, whether we're in dev, what version of webpack we're using, etc). Note that @@ -511,7 +511,7 @@ function findTranspilationRules(rules: WebpackModuleRule[] | undefined, projectD async function addSentryToEntryProperty( currentEntryProperty: WebpackEntryProperty, buildContext: BuildContext, - userSentryOptions: UserSentryOptions, + userSentryOptions: SentryBuildtimeOptions, ): Promise { // The `entry` entry in a webpack config can be a string, array of strings, object, or function. By default, nextjs // sets it to an async function which returns the promise of an object of string arrays. Because we don't know whether @@ -725,7 +725,7 @@ function shouldAddSentryToEntryPoint(entryPointName: string, runtime: 'node' | ' export function getWebpackPluginOptions( buildContext: BuildContext, userPluginOptions: Partial, - userSentryOptions: UserSentryOptions, + userSentryOptions: SentryBuildtimeOptions, ): SentryWebpackPluginOptions { const { buildId, isServer, config, dir: projectDir } = buildContext; const userNextConfig = config as NextConfigObject; @@ -884,7 +884,7 @@ export function getWebpackPluginOptions( } /** Check various conditions to decide if we should run the plugin */ -function shouldEnableWebpackPlugin(buildContext: BuildContext, userSentryOptions: UserSentryOptions): boolean { +function shouldEnableWebpackPlugin(buildContext: BuildContext, userSentryOptions: SentryBuildtimeOptions): boolean { const { isServer } = buildContext; const { disableServerWebpackPlugin, disableClientWebpackPlugin } = userSentryOptions; @@ -900,7 +900,7 @@ function shouldEnableWebpackPlugin(buildContext: BuildContext, userSentryOptions /** Handle warning messages about `hideSourceMaps` option. Can be removed in v9 or v10 (or whenever we consider that * enough people will have upgraded the SDK that the warning about the default in v8 - currently commented out - is * overkill). */ -function handleSourcemapHidingOptionWarning(userSentryOptions: UserSentryOptions, isServer: boolean): void { +function handleSourcemapHidingOptionWarning(userSentryOptions: SentryBuildtimeOptions, isServer: boolean): void { // This is nextjs's own logging formatting, vendored since it's not exported. See // https://github.com/vercel/next.js/blob/c3ceeb03abb1b262032bd96457e224497d3bbcef/packages/next/build/output/log.ts#L3-L11 // and @@ -969,7 +969,7 @@ function setUpModuleRules(newConfig: WebpackConfigObject): WebpackConfigObjectWi function addValueInjectionLoader( newConfig: WebpackConfigObjectWithModuleRules, userNextConfig: NextConfigObject, - userSentryOptions: UserSentryOptions, + userSentryOptions: SentryBuildtimeOptions, buildContext: BuildContext, sentryWebpackPluginOptions: Partial, ): void { diff --git a/packages/nextjs/src/config/withSentryConfig.ts b/packages/nextjs/src/config/withSentryConfig.ts index 6a9fae6f3a79..446a09be79ee 100644 --- a/packages/nextjs/src/config/withSentryConfig.ts +++ b/packages/nextjs/src/config/withSentryConfig.ts @@ -5,24 +5,24 @@ import type { NextConfigFunction, NextConfigObject, SentryWebpackPluginOptions, - UserSentryOptions, + SentryBuildtimeOptions, } from './types'; import { constructWebpackConfigFunction } from './webpack'; let showedExportModeTunnelWarning = false; /** - * Modifies the passed in Next.js configuration + * Modifies the passed in Next.js configuration with automatic build-time instrumentation and source map upload. * - * @param nextConfig The existing config to be exported prior to adding Sentry - * @param sentryWebpackPluginOptions Configuration for SentryWebpackPlugin - * @param sentrySDKOptions Optional additional options to add as alternative to `sentry` property of config + * @param nextConfig A Next.js configuration object, as usually exported in `next.config.js` or `next.config.mjs`. + * @param sentryWebpackPluginOptions Options to configure the automatically included Sentry Webpack Plugin for source maps and release management in Sentry. + * @param sentryBuildtimeOptions Additional options to configure instrumentation and * @returns The modified config to be exported */ export function withSentryConfig( nextConfig: NextConfig = {}, sentryWebpackPluginOptions: Partial = {}, - sentrySDKOptions: UserSentryOptions = {}, + sentryBuildtimeOptions: SentryBuildtimeOptions = {}, ): NextConfigFunction | NextConfigObject { if (typeof nextConfig === 'function') { return function (this: unknown, ...webpackConfigFunctionArgs: unknown[]): ReturnType { @@ -30,14 +30,14 @@ export function withSentryConfig( if (isThenable(maybePromiseNextConfig)) { return maybePromiseNextConfig.then(promiseResultNextConfig => { - return getFinalConfigObject(promiseResultNextConfig, sentrySDKOptions, sentryWebpackPluginOptions); + return getFinalConfigObject(promiseResultNextConfig, sentryBuildtimeOptions, sentryWebpackPluginOptions); }); } - return getFinalConfigObject(maybePromiseNextConfig, sentrySDKOptions, sentryWebpackPluginOptions); + return getFinalConfigObject(maybePromiseNextConfig, sentryBuildtimeOptions, sentryWebpackPluginOptions); }; } else { - return getFinalConfigObject(nextConfig, sentrySDKOptions, sentryWebpackPluginOptions); + return getFinalConfigObject(nextConfig, sentryBuildtimeOptions, sentryWebpackPluginOptions); } } @@ -45,7 +45,7 @@ export function withSentryConfig( // `webpack` property function getFinalConfigObject( incomingUserNextConfigObject: NextConfigObject, - userSentryOptions: UserSentryOptions, + userSentryOptions: SentryBuildtimeOptions, userSentryWebpackPluginOptions: Partial, ): NextConfigObject { if ('sentry' in incomingUserNextConfigObject) { diff --git a/packages/nextjs/test/config/fixtures.ts b/packages/nextjs/test/config/fixtures.ts index 69f15a18f088..7da47e37be33 100644 --- a/packages/nextjs/test/config/fixtures.ts +++ b/packages/nextjs/test/config/fixtures.ts @@ -3,7 +3,6 @@ import type { EntryPropertyFunction, ExportedNextConfig, NextConfigObject, - NextConfigObjectWithSentry, WebpackConfigObject, } from '../../src/config/types'; @@ -26,7 +25,7 @@ export const userNextConfig: NextConfigObject = { }; /** Mocks of the arguments passed to `withSentryConfig` */ -export const exportedNextConfig = userNextConfig as NextConfigObjectWithSentry; +export const exportedNextConfig = userNextConfig; export const userSentryWebpackPluginConfig = { org: 'squirrelChasers', project: 'simulator' }; process.env.SENTRY_AUTH_TOKEN = 'dogsarebadatkeepingsecrets'; process.env.SENTRY_RELEASE = 'doGsaREgReaT'; diff --git a/packages/nextjs/test/config/testUtils.ts b/packages/nextjs/test/config/testUtils.ts index c9bed5dbe358..3b4062083f46 100644 --- a/packages/nextjs/test/config/testUtils.ts +++ b/packages/nextjs/test/config/testUtils.ts @@ -6,6 +6,7 @@ import type { EntryPropertyFunction, ExportedNextConfig, NextConfigObject, + SentryBuildtimeOptions, SentryWebpackPluginOptions, WebpackConfigObject, WebpackConfigObjectWithModuleRules, @@ -28,8 +29,9 @@ export function materializeFinalNextConfig( exportedNextConfig: ExportedNextConfig, userSentryWebpackPluginConfig?: Partial, runtimePhase?: string, + sentryBuildTimeOptions?: SentryBuildtimeOptions, ): NextConfigObject { - const sentrifiedConfig = withSentryConfig(exportedNextConfig, userSentryWebpackPluginConfig); + const sentrifiedConfig = withSentryConfig(exportedNextConfig, userSentryWebpackPluginConfig, sentryBuildTimeOptions); let finalConfigValues = sentrifiedConfig; if (typeof sentrifiedConfig === 'function') { @@ -59,6 +61,7 @@ export async function materializeFinalWebpackConfig(options: { userSentryWebpackPluginConfig?: Partial; incomingWebpackConfig: WebpackConfigObject; incomingWebpackBuildContext: BuildContext; + sentryBuildTimeOptions?: SentryBuildtimeOptions; }): Promise { const { exportedNextConfig, userSentryWebpackPluginConfig, incomingWebpackConfig, incomingWebpackBuildContext } = options; @@ -69,15 +72,11 @@ export async function materializeFinalWebpackConfig(options: { ? await exportedNextConfig('phase-production-build', defaultsObject) : exportedNextConfig; - // extract the `sentry` property as we do in `withSentryConfig` - const { sentry: sentryConfig } = materializedUserNextConfig; - delete materializedUserNextConfig.sentry; - // get the webpack config function we'd normally pass back to next const webpackConfigFunction = constructWebpackConfigFunction( materializedUserNextConfig, userSentryWebpackPluginConfig, - sentryConfig, + options.sentryBuildTimeOptions ?? {}, ); // call it to get concrete values for comparison diff --git a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts index b70e6d3d642e..ed101058a57e 100644 --- a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts +++ b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts @@ -48,36 +48,38 @@ describe('constructWebpackConfigFunction()', () => { }); it("doesn't set devtool if webpack plugin is disabled", () => { - const finalNextConfig = materializeFinalNextConfig({ - ...exportedNextConfig, - webpack: () => - ({ - ...serverWebpackConfig, - devtool: 'something-besides-source-map', - }) as any, - sentry: { disableServerWebpackPlugin: true }, - }); + const finalNextConfig = materializeFinalNextConfig( + { + ...exportedNextConfig, + webpack: () => + ({ + ...serverWebpackConfig, + devtool: 'something-besides-source-map', + }) as any, + }, + undefined, + undefined, + { disableServerWebpackPlugin: true }, + ); + const finalWebpackConfig = finalNextConfig.webpack?.(serverWebpackConfig, serverBuildContext); expect(finalWebpackConfig?.devtool).not.toEqual('source-map'); }); it('allows for the use of `hidden-source-map` as `devtool` value for client-side builds', async () => { - const exportedNextConfigHiddenSourceMaps = { - ...exportedNextConfig, - sentry: { ...exportedNextConfig.sentry, hideSourceMaps: true }, - }; - const finalClientWebpackConfig = await materializeFinalWebpackConfig({ - exportedNextConfig: exportedNextConfigHiddenSourceMaps, + exportedNextConfig: exportedNextConfig, incomingWebpackConfig: clientWebpackConfig, incomingWebpackBuildContext: clientBuildContext, + sentryBuildTimeOptions: { hideSourceMaps: true }, }); const finalServerWebpackConfig = await materializeFinalWebpackConfig({ - exportedNextConfig: exportedNextConfigHiddenSourceMaps, + exportedNextConfig: exportedNextConfig, incomingWebpackConfig: serverWebpackConfig, incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { hideSourceMaps: true }, }); expect(finalClientWebpackConfig.devtool).toEqual('hidden-source-map'); diff --git a/packages/nextjs/test/config/webpack/sentryWebpackPlugin.test.ts b/packages/nextjs/test/config/webpack/sentryWebpackPlugin.test.ts index ddcc8965a6c1..f75aae23046b 100644 --- a/packages/nextjs/test/config/webpack/sentryWebpackPlugin.test.ts +++ b/packages/nextjs/test/config/webpack/sentryWebpackPlugin.test.ts @@ -3,7 +3,7 @@ import * as os from 'os'; import * as path from 'path'; import { default as SentryWebpackPlugin } from '@sentry/webpack-plugin'; -import type { BuildContext, ExportedNextConfig } from '../../../src/config/types'; +import type { BuildContext, ExportedNextConfig, SentryBuildtimeOptions } from '../../../src/config/types'; import { getUserConfigFile, getWebpackPluginOptions } from '../../../src/config/webpack'; import { clientBuildContext, @@ -83,13 +83,14 @@ describe('Sentry webpack plugin config', () => { }); it('has the correct value when building client bundles using `widenClientFileUpload` option', async () => { - const exportedNextConfigWithWidening = { ...exportedNextConfig, sentry: { widenClientFileUpload: true } }; + const exportedNextConfigWithWidening = { ...exportedNextConfig }; const buildContext = getBuildContext('client', exportedNextConfigWithWidening); const finalWebpackConfig = await materializeFinalWebpackConfig({ exportedNextConfig: exportedNextConfigWithWidening, incomingWebpackConfig: clientWebpackConfig, incomingWebpackBuildContext: buildContext, + sentryBuildTimeOptions: { widenClientFileUpload: true }, }); const sentryWebpackPluginInstance = findWebpackPlugin( @@ -180,11 +181,12 @@ describe('Sentry webpack plugin config', () => { }); it('has the correct value when building client bundles using `widenClientFileUpload` option', async () => { - const exportedNextConfigWithWidening = { ...exportedNextConfig, sentry: { widenClientFileUpload: true } }; + const exportedNextConfigWithWidening = { ...exportedNextConfig }; const finalWebpackConfig = await materializeFinalWebpackConfig({ exportedNextConfig: exportedNextConfigWithWidening, incomingWebpackConfig: clientWebpackConfig, incomingWebpackBuildContext: getBuildContext('client', exportedNextConfigWithWidening), + sentryBuildTimeOptions: { widenClientFileUpload: true }, }); const sentryWebpackPluginInstance = findWebpackPlugin( @@ -219,8 +221,8 @@ describe('Sentry webpack plugin config', () => { 'obeys `disableClientWebpackPlugin = true`', { ...exportedNextConfig, - sentry: { disableClientWebpackPlugin: true }, }, + { disableClientWebpackPlugin: true }, {}, true, false, @@ -230,8 +232,8 @@ describe('Sentry webpack plugin config', () => { 'obeys `disableServerWebpackPlugin = true`', { ...exportedNextConfig, - sentry: { disableServerWebpackPlugin: true }, }, + { disableServerWebpackPlugin: true }, {}, false, true, @@ -241,6 +243,7 @@ describe('Sentry webpack plugin config', () => { async ( _testName: string, exportedNextConfig: ExportedNextConfig, + buildTimeOptions: SentryBuildtimeOptions, extraEnvValues: Record, shouldFindServerPlugin: boolean, shouldFindClientPlugin: boolean, @@ -254,6 +257,7 @@ describe('Sentry webpack plugin config', () => { userSentryWebpackPluginConfig, incomingWebpackConfig: serverWebpackConfig, incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: buildTimeOptions, }); const clientFinalWebpackConfig = await materializeFinalWebpackConfig({ @@ -261,6 +265,7 @@ describe('Sentry webpack plugin config', () => { userSentryWebpackPluginConfig, incomingWebpackConfig: clientWebpackConfig, incomingWebpackBuildContext: clientBuildContext, + sentryBuildTimeOptions: buildTimeOptions, }); const genericSentryWebpackPluginInstance = expect.any(SentryWebpackPlugin); diff --git a/packages/nextjs/test/config/withSentryConfig.test.ts b/packages/nextjs/test/config/withSentryConfig.test.ts index 4ed6f2d40770..e457174f5fa9 100644 --- a/packages/nextjs/test/config/withSentryConfig.test.ts +++ b/packages/nextjs/test/config/withSentryConfig.test.ts @@ -49,14 +49,4 @@ describe('withSentryConfig', () => { expect(exportedNextConfigFunction).toHaveBeenCalledWith(defaultRuntimePhase, defaultsObject); }); - - it('removes `sentry` property', () => { - // It's unclear why we need this cast - - const finalConfig = materializeFinalNextConfig({ ...exportedNextConfig, sentry: {} }); - // const finalConfig = materializeFinalNextConfig({ ...exportedNextConfig, sentry: {} } as ExportedNextConfig); - - // We have to check using `in` because TS knows it shouldn't be there and throws a type error if we try to access it - // directly - expect('sentry' in finalConfig).toBe(false); - }); }); From 4c059e167cbbf363355a9e92b8efccb802cc1fe2 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 28 Feb 2024 13:00:04 +0000 Subject: [PATCH 3/4] lint --- packages/nextjs/src/config/webpack.ts | 2 +- packages/nextjs/src/config/withSentryConfig.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 5c0c57e7251c..5a1c9ede21b4 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -17,8 +17,8 @@ import type { BuildContext, EntryPropertyObject, NextConfigObject, - SentryWebpackPluginOptions, SentryBuildtimeOptions, + SentryWebpackPluginOptions, WebpackConfigFunction, WebpackConfigObject, WebpackConfigObjectWithModuleRules, diff --git a/packages/nextjs/src/config/withSentryConfig.ts b/packages/nextjs/src/config/withSentryConfig.ts index 446a09be79ee..90af76cca813 100644 --- a/packages/nextjs/src/config/withSentryConfig.ts +++ b/packages/nextjs/src/config/withSentryConfig.ts @@ -4,8 +4,8 @@ import type { ExportedNextConfig as NextConfig, NextConfigFunction, NextConfigObject, - SentryWebpackPluginOptions, SentryBuildtimeOptions, + SentryWebpackPluginOptions, } from './types'; import { constructWebpackConfigFunction } from './webpack'; From 3329e24bc534e57550ba96310910588d5b1497da Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 5 Mar 2024 09:11:59 +0000 Subject: [PATCH 4/4] Move migration section --- MIGRATION.md | 80 +++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 27433d52a455..f6a6ba0a98f4 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -500,6 +500,45 @@ The following previously deprecated API has been removed from the `@sentry/nextj - `IS_BUILD` - `isBuild` +#### Removal of the `sentry` property in your Next.js options (next.config.js) + +With version 8 of the Sentry Next.js SDK, the SDK will no longer support passing Next.js options with a `sentry` +property to `withSentryConfig`. Please use the third argument of `withSentryConfig` to configure the SDK instead: + +```ts +// OLD +const nextConfig = { + // Your Next.js options... + + sentry: { + // Your Sentry SDK options... + }, +}; + +module.exports = withSentryConfig(nextConfig, { + // Your Sentry Webpack Plugin Options... +}); + +// NEW +const nextConfig = { + // Your Next.js options... +}; + +module.exports = withSentryConfig( + nextConfig, + { + // Your Sentry Webpack Plugin Options... + }, + { + // Your Sentry SDK options... + }, +); +``` + +The reason for this change is to have one consistent way of defining the SDK options. We hope that this change will +reduce confusion when setting up the SDK, with the upside that the explicit option is properly typed and will therefore +have code completion. + ### Astro SDK #### Removal of `trackHeaders` option for Astro middleware @@ -579,47 +618,6 @@ The SDK no longer filters out health check transactions by default. Instead, the by the Sentry backend by default. You can disable dropping them in your Sentry project settings. If you still want to drop specific transactions within the SDK you can either use the `ignoreTransactions` SDK option. -## Next.js SDK Changes - -### Removal of the `sentry` property in your Next.js options - -With version 8 of the Sentry Next.js SDK, the SDK will no longer support passing Next.js options with a `sentry` -property to `withSentryConfig`. Please use the third argument of `withSentryConfig` to configure the SDK instead: - -```ts -// OLD -const nextConfig = { - // Your Next.js options... - - sentry: { - // Your Sentry SDK options... - }, -}; - -module.exports = withSentryConfig(nextConfig, { - // Your Sentry Webpack Plugin Options... -}); - -// NEW -const nextConfig = { - // Your Next.js options... -}; - -module.exports = withSentryConfig( - nextConfig, - { - // Your Sentry Webpack Plugin Options... - }, - { - // Your Sentry SDK options... - }, -); -``` - -The reason for this change is to have one consistent way of defining the SDK options. We hope that this change will -reduce confusion when setting up the SDK, with the upside that the explicit option is properly typed and will therefore -have code completion. - # Deprecations in 7.x You can use the **Experimental** [@sentry/migr8](https://www.npmjs.com/package/@sentry/migr8) to automatically update