Skip to content

Commit

Permalink
ref(nextjs): Simplify NextConfigObject type (#5514)
Browse files Browse the repository at this point in the history
This simplifies the `NextConfigObject` type in the nextjs SDK, to enable future work. Key changes:
- Removed index signature.
- Added missing `basePath` and `publicRuntimeConfig` properties.
- Made all properties optional. (This allowed for removal of the `Partial` annotation everywhere the type was used.)
- Clarified variable names in `config/index.ts` to better reflect their types.
  • Loading branch information
lobsterkatie committed Aug 2, 2022
1 parent 6f4ad56 commit 9b7131f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 29 deletions.
30 changes: 15 additions & 15 deletions 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<SentryWebpackPluginOptions> = {},
): NextConfigFunction | Partial<NextConfigObject> {
): 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<NextConfigObject> {
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,
),
Expand All @@ -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),
};
}
20 changes: 9 additions & 11 deletions packages/nextjs/src/config/types.ts
Expand Up @@ -8,19 +8,20 @@ export type SentryWebpackPlugin = WebpackPluginInstance & { options: SentryWebpa
* Overall Nextjs config
*/

export type ExportedNextConfig = Partial<NextConfigObject> | 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 = {
Expand All @@ -40,10 +41,7 @@ export type UserSentryOptions = {
widenClientFileUpload?: boolean;
};

export type NextConfigFunction = (
phase: string,
defaults: { defaultConfig: NextConfigObject },
) => Partial<NextConfigObject>;
export type NextConfigFunction = (phase: string, defaults: { defaultConfig: NextConfigObject }) => NextConfigObject;

/**
* Webpack config
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/src/config/webpack.ts
Expand Up @@ -36,7 +36,7 @@ export { SentryWebpackPlugin };
* @returns The function to set as the nextjs config's `webpack` value
*/
export function constructWebpackConfigFunction(
userNextConfig: Partial<NextConfigObject> = {},
userNextConfig: NextConfigObject = {},
userSentryWebpackPluginOptions: Partial<SentryWebpackPluginOptions> = {},
userSentryOptions: UserSentryOptions = {},
): WebpackConfigFunction {
Expand Down
4 changes: 2 additions & 2 deletions packages/nextjs/test/config.test.ts
Expand Up @@ -64,7 +64,7 @@ afterEach(() => {
});

/** Mocks of the arguments passed to `withSentryConfig` */
const userNextConfig: Partial<NextConfigObject> = {
const userNextConfig: NextConfigObject = {
publicRuntimeConfig: { location: 'dogpark', activities: ['fetch', 'chasing', 'digging'] },
webpack: (config: WebpackConfigObject, _options: BuildContext) => ({
...config,
Expand Down Expand Up @@ -124,7 +124,7 @@ const clientWebpackConfig = {
// dynamically.
function getBuildContext(
buildTarget: 'server' | 'client',
userNextConfig: Partial<NextConfigObject>,
userNextConfig: NextConfigObject,
webpackVersion: string = '5.4.15',
): BuildContext {
return {
Expand Down

0 comments on commit 9b7131f

Please sign in to comment.