diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index 7138dbdf0e37..dacb9adc2b4c 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -1,33 +1,33 @@ -import { ExportedNextConfig, NextConfigFunction, NextConfigObject, SentryWebpackPluginOptions } from './types'; +import type { ExportedNextConfig, NextConfigFunction, NextConfigObject, SentryWebpackPluginOptions } from './types'; import { constructWebpackConfigFunction } from './webpack'; /** * Add Sentry options to the config to be exported from the user's `next.config.js` file. * - * @param userNextConfig The existing config to be exported prior to adding Sentry + * @param exportedUserNextConfig The existing config to be exported prior to adding Sentry * @param userSentryWebpackPluginOptions Configuration for SentryWebpackPlugin * @returns The modified config to be exported */ export function withSentryConfig( - userNextConfig: ExportedNextConfig = {}, + exportedUserNextConfig: ExportedNextConfig = {}, userSentryWebpackPluginOptions: Partial = {}, -): NextConfigFunction | Partial { +): NextConfigFunction | NextConfigObject { // If the user has passed us a function, we need to return a function, so that we have access to `phase` and // `defaults` in order to pass them along to the user's function - if (typeof userNextConfig === 'function') { - return function (phase: string, defaults: { defaultConfig: NextConfigObject }): Partial { - const materializedUserNextConfig = userNextConfig(phase, defaults); + if (typeof exportedUserNextConfig === 'function') { + return function (phase: string, defaults: { defaultConfig: NextConfigObject }): NextConfigObject { + const userNextConfigObject = exportedUserNextConfig(phase, defaults); // Next 12.2.3+ warns about non-canonical properties on `userNextConfig`, so grab and then remove the `sentry` // property there. Where we actually need it is in the webpack config function we're going to create, so pass it // to `constructWebpackConfigFunction` so that it will be in the created function's closure. - const { sentry: userSentryOptions } = materializedUserNextConfig; - delete materializedUserNextConfig.sentry; + const { sentry: userSentryOptions } = userNextConfigObject; + delete userNextConfigObject.sentry; return { - ...materializedUserNextConfig, + ...userNextConfigObject, webpack: constructWebpackConfigFunction( - materializedUserNextConfig, + userNextConfigObject, userSentryWebpackPluginOptions, userSentryOptions, ), @@ -39,11 +39,11 @@ export function withSentryConfig( // Prevent nextjs from getting mad about having a non-standard config property in `userNextConfig`. (See note above // for a more thorough explanation of what we're doing here.) - const { sentry: userSentryOptions } = userNextConfig; - delete userNextConfig.sentry; + const { sentry: userSentryOptions } = exportedUserNextConfig; + delete exportedUserNextConfig.sentry; return { - ...userNextConfig, - webpack: constructWebpackConfigFunction(userNextConfig, userSentryWebpackPluginOptions, userSentryOptions), + ...exportedUserNextConfig, + webpack: constructWebpackConfigFunction(exportedUserNextConfig, userSentryWebpackPluginOptions, userSentryOptions), }; } diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index e1de856ab26b..17ccbe12a5f0 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -8,19 +8,20 @@ export type SentryWebpackPlugin = WebpackPluginInstance & { options: SentryWebpa * Overall Nextjs config */ -export type ExportedNextConfig = Partial | NextConfigFunction; +export type ExportedNextConfig = NextConfigObject | NextConfigFunction; export type NextConfigObject = { // custom webpack options - webpack: WebpackConfigFunction; + webpack?: WebpackConfigFunction; // whether to build serverless functions for all pages, not just API routes - target: 'server' | 'experimental-serverless-trace'; + target?: 'server' | 'experimental-serverless-trace'; // the output directory for the built app (defaults to ".next") - distDir: string; + distDir?: string; + // the root at which the nextjs app will be served (defaults to "/") + basePath?: string; + // config which will be available at runtime + publicRuntimeConfig?: { [key: string]: unknown }; sentry?: UserSentryOptions; -} & { - // other `next.config.js` options - [key: string]: unknown; }; export type UserSentryOptions = { @@ -40,10 +41,7 @@ export type UserSentryOptions = { widenClientFileUpload?: boolean; }; -export type NextConfigFunction = ( - phase: string, - defaults: { defaultConfig: NextConfigObject }, -) => Partial; +export type NextConfigFunction = (phase: string, defaults: { defaultConfig: NextConfigObject }) => NextConfigObject; /** * Webpack config diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 13c970657811..ecbbe226a12b 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -36,7 +36,7 @@ export { SentryWebpackPlugin }; * @returns The function to set as the nextjs config's `webpack` value */ export function constructWebpackConfigFunction( - userNextConfig: Partial = {}, + userNextConfig: NextConfigObject = {}, userSentryWebpackPluginOptions: Partial = {}, userSentryOptions: UserSentryOptions = {}, ): WebpackConfigFunction { diff --git a/packages/nextjs/test/config.test.ts b/packages/nextjs/test/config.test.ts index 1ca18e191f9c..a42209501a5a 100644 --- a/packages/nextjs/test/config.test.ts +++ b/packages/nextjs/test/config.test.ts @@ -64,7 +64,7 @@ afterEach(() => { }); /** Mocks of the arguments passed to `withSentryConfig` */ -const userNextConfig: Partial = { +const userNextConfig: NextConfigObject = { publicRuntimeConfig: { location: 'dogpark', activities: ['fetch', 'chasing', 'digging'] }, webpack: (config: WebpackConfigObject, _options: BuildContext) => ({ ...config, @@ -124,7 +124,7 @@ const clientWebpackConfig = { // dynamically. function getBuildContext( buildTarget: 'server' | 'client', - userNextConfig: Partial, + userNextConfig: NextConfigObject, webpackVersion: string = '5.4.15', ): BuildContext { return {