From 4d8827247dbfb3c80227048d5ecad4b495e789b7 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 10:20:26 +0200 Subject: [PATCH 01/16] feat(nextjs): Support `distDir` Next.js option --- packages/nextjs/src/config/index.ts | 61 +++++++++++++++++++++++++-- packages/nextjs/src/config/webpack.ts | 9 ++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index 5cc4d5964893..fb032851d3ad 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -12,18 +12,71 @@ export function withSentryConfig( userNextConfig: ExportedNextConfig = {}, userSentryWebpackPluginOptions: 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 + const webpackPluginOptionsWithSources = includeSources(userNextConfig, userSentryWebpackPluginOptions); + if (typeof userNextConfig === 'function') { + // 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 return function(phase: string, defaults: { defaultConfig: NextConfigObject }): NextConfigObject { const materializedUserNextConfig = userNextConfig(phase, defaults); + const sentryWebpackPluginOptionsWithSources = includeSources( + materializedUserNextConfig, + userSentryWebpackPluginOptions, + ); return { ...materializedUserNextConfig, - webpack: constructWebpackConfigFunction(materializedUserNextConfig, userSentryWebpackPluginOptions), + webpack: constructWebpackConfigFunction(materializedUserNextConfig, sentryWebpackPluginOptionsWithSources), }; }; } // Otherwise, we can just merge their config with ours and return an object. - return { ...userNextConfig, webpack: constructWebpackConfigFunction(userNextConfig, userSentryWebpackPluginOptions) }; + return { + ...userNextConfig, + webpack: constructWebpackConfigFunction(userNextConfig, webpackPluginOptionsWithSources), + }; +} + +function includeSources( + nextConfig: ExportedNextConfig, + sentryWebpackPluginOptions: Partial, +): Partial { + if (!nextConfig.distDir) { + return sentryWebpackPluginOptions; + } + const usersInclude = sentryWebpackPluginOptions.include; + + let sourcesToInclude; + if (typeof usersInclude === 'undefined') { + sourcesToInclude = nextConfig.distDir; + } else if (typeof usersInclude === 'string') { + sourcesToInclude = [usersInclude, nextConfig.distDir]; + } else if (Array.isArray(usersInclude)) { + sourcesToInclude = [...new Set(usersInclude.concat(nextConfig.distDir))]; + } else { + // Object + if (Array.isArray(usersInclude.paths)) { + const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir))]; + sourcesToInclude = { ...usersInclude, paths: uniquePaths }; + } else if (typeof usersInclude.paths === 'undefined') { + // eslint-disable-next-line no-console + console.warn( + 'Sentry Logger [Warn]:', + `An object was set in \`include\` but no \`paths\` was provided, so added the \`distDir\`: "${nextConfig.distDir}"\n` + + 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', + ); + sourcesToInclude = { ...usersInclude, paths: [nextConfig.distDir] }; + } else { + // eslint-disable-next-line no-console + console.error( + 'Sentry Logger [Error]:', + 'Found unexpected object in `include.paths`\n' + + 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', + ); + // Keep the same object even if it's incorrect, so that the user can get a more precise error from sentry-cli + sourcesToInclude = usersInclude.paths; + } + } + + return { ...sentryWebpackPluginOptions, include: sourcesToInclude }; } diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 76dd5a8382da..5888b267b71a 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -261,6 +261,7 @@ function getWebpackPluginOptions( userPluginOptions: Partial, ): SentryWebpackPluginOptions { const { isServer, dir: projectDir, buildId, dev: isDev, config: nextConfig, webpack } = buildContext; + const distDir = nextConfig.distDir || '.next'; // `.next` is the default directory const isWebpack5 = webpack.version.startsWith('5'); const isServerless = nextConfig.target === 'experimental-serverless-trace'; @@ -268,12 +269,12 @@ function getWebpackPluginOptions( const urlPrefix = nextConfig.basePath ? `~${nextConfig.basePath}/_next` : '~/_next'; const serverInclude = isServerless - ? [{ paths: ['.next/serverless/'], urlPrefix: `${urlPrefix}/serverless` }] - : [{ paths: ['.next/server/pages/'], urlPrefix: `${urlPrefix}/server/pages` }].concat( - isWebpack5 ? [{ paths: ['.next/server/chunks/'], urlPrefix: `${urlPrefix}/server/chunks` }] : [], + ? [{ paths: [`${distDir}/serverless/`], urlPrefix: `${urlPrefix}/serverless` }] + : [{ paths: [`${distDir}/server/pages/`], urlPrefix: `${urlPrefix}/server/pages` }].concat( + isWebpack5 ? [{ paths: [`${distDir}/server/chunks/`], urlPrefix: `${urlPrefix}/server/chunks` }] : [], ); - const clientInclude = [{ paths: ['.next/static/chunks/pages'], urlPrefix: `${urlPrefix}/static/chunks/pages` }]; + const clientInclude = [{ paths: [`${distDir}/static/chunks/pages`], urlPrefix: `${urlPrefix}/static/chunks/pages` }]; const defaultPluginOptions = dropUndefinedKeys({ include: isServer ? serverInclude : clientInclude, From cb9461833af5f0caf302235ef7414ee4381a9071 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 10:22:18 +0200 Subject: [PATCH 02/16] Move the comment back to its original place --- packages/nextjs/src/config/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index fb032851d3ad..f5558a01db7c 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -14,9 +14,9 @@ export function withSentryConfig( ): NextConfigFunction | NextConfigObject { const webpackPluginOptionsWithSources = includeSources(userNextConfig, userSentryWebpackPluginOptions); + // 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') { - // 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 return function(phase: string, defaults: { defaultConfig: NextConfigObject }): NextConfigObject { const materializedUserNextConfig = userNextConfig(phase, defaults); const sentryWebpackPluginOptionsWithSources = includeSources( From 042223b1818165c6b815b5897c47ca785e44f4bd Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 14:12:12 +0200 Subject: [PATCH 03/16] Separate `includeSources` to another file --- packages/nextjs/src/config/index.ts | 49 +--------------- .../config/nextConfigToWebpackPluginConfig.ts | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index f5558a01db7c..59286741a5c5 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -1,3 +1,4 @@ +import { includeDistDir } from './nextConfigToWebpackPluginConfig'; import { ExportedNextConfig, NextConfigFunction, NextConfigObject, SentryWebpackPluginOptions } from './types'; import { constructWebpackConfigFunction } from './webpack'; @@ -12,14 +13,14 @@ export function withSentryConfig( userNextConfig: ExportedNextConfig = {}, userSentryWebpackPluginOptions: Partial = {}, ): NextConfigFunction | NextConfigObject { - const webpackPluginOptionsWithSources = includeSources(userNextConfig, userSentryWebpackPluginOptions); + const webpackPluginOptionsWithSources = includeDistDir(userNextConfig, userSentryWebpackPluginOptions); // 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 }): NextConfigObject { const materializedUserNextConfig = userNextConfig(phase, defaults); - const sentryWebpackPluginOptionsWithSources = includeSources( + const sentryWebpackPluginOptionsWithSources = includeDistDir( materializedUserNextConfig, userSentryWebpackPluginOptions, ); @@ -36,47 +37,3 @@ export function withSentryConfig( webpack: constructWebpackConfigFunction(userNextConfig, webpackPluginOptionsWithSources), }; } - -function includeSources( - nextConfig: ExportedNextConfig, - sentryWebpackPluginOptions: Partial, -): Partial { - if (!nextConfig.distDir) { - return sentryWebpackPluginOptions; - } - const usersInclude = sentryWebpackPluginOptions.include; - - let sourcesToInclude; - if (typeof usersInclude === 'undefined') { - sourcesToInclude = nextConfig.distDir; - } else if (typeof usersInclude === 'string') { - sourcesToInclude = [usersInclude, nextConfig.distDir]; - } else if (Array.isArray(usersInclude)) { - sourcesToInclude = [...new Set(usersInclude.concat(nextConfig.distDir))]; - } else { - // Object - if (Array.isArray(usersInclude.paths)) { - const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir))]; - sourcesToInclude = { ...usersInclude, paths: uniquePaths }; - } else if (typeof usersInclude.paths === 'undefined') { - // eslint-disable-next-line no-console - console.warn( - 'Sentry Logger [Warn]:', - `An object was set in \`include\` but no \`paths\` was provided, so added the \`distDir\`: "${nextConfig.distDir}"\n` + - 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', - ); - sourcesToInclude = { ...usersInclude, paths: [nextConfig.distDir] }; - } else { - // eslint-disable-next-line no-console - console.error( - 'Sentry Logger [Error]:', - 'Found unexpected object in `include.paths`\n' + - 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', - ); - // Keep the same object even if it's incorrect, so that the user can get a more precise error from sentry-cli - sourcesToInclude = usersInclude.paths; - } - } - - return { ...sentryWebpackPluginOptions, include: sourcesToInclude }; -} diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts new file mode 100644 index 000000000000..cb97a4bcf91e --- /dev/null +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -0,0 +1,58 @@ +import { ExportedNextConfig, SentryWebpackPluginOptions } from './types'; + +/** + * Creates a new Sentry Webpack Plugin config with the `distDir` option from Next.js config + * in the `include` property. + * + * If no `distDir` is provided, the Webpack Plugin config doesn't change. + * If no `include` has been defined defined, the `distDir` value is assigned. + * The `distDir` directory is merged to the directories in `include`, if defined. + * Duplicated paths are removed while merging. + * + * @param nextConfig User's Next.js config + * @param sentryWebpackPluginOptions User's Sentry Webpack Plugin config + * @returns New Sentry Webpack Plugin config + */ +export function includeDistDir( + nextConfig: ExportedNextConfig, + sentryWebpackPluginOptions: Partial, +): Partial { + if (!nextConfig.distDir) { + return { ...sentryWebpackPluginOptions }; + } + const usersInclude = sentryWebpackPluginOptions.include; + + let sourcesToInclude; + if (typeof usersInclude === 'undefined') { + sourcesToInclude = nextConfig.distDir; + } else if (typeof usersInclude === 'string') { + sourcesToInclude = usersInclude === nextConfig.distDir ? usersInclude : [usersInclude, nextConfig.distDir]; + } else if (Array.isArray(usersInclude)) { + sourcesToInclude = [...new Set(usersInclude.concat(nextConfig.distDir))]; + } else { + // Object + if (Array.isArray(usersInclude.paths)) { + const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir))]; + sourcesToInclude = { ...usersInclude, paths: uniquePaths }; + } else if (typeof usersInclude.paths === 'undefined') { + // eslint-disable-next-line no-console + console.warn( + 'Sentry Logger [Warn]:', + `An object was set in \`include\` but no \`paths\` was provided, so added the \`distDir\`: "${nextConfig.distDir}"\n` + + 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', + ); + sourcesToInclude = { ...usersInclude, paths: [nextConfig.distDir] }; + } else { + // eslint-disable-next-line no-console + console.error( + 'Sentry Logger [Error]:', + 'Found unexpected object in `include.paths`\n' + + 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', + ); + // Keep the same object even if it's incorrect, so that the user can get a more precise error from sentry-cli + sourcesToInclude = usersInclude; + } + } + + return { ...sentryWebpackPluginOptions, include: sourcesToInclude }; +} From 80144135b37615cc9c96b481cc464c3a757f04e3 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 14:16:03 +0200 Subject: [PATCH 04/16] Add unit tests to `includeDistDir` --- .../nextConfigToWebpackPluginConfig.test.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts diff --git a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts new file mode 100644 index 000000000000..b10aab4b2158 --- /dev/null +++ b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts @@ -0,0 +1,65 @@ +import { includeDistDir } from '../../src/config/nextConfigToWebpackPluginConfig'; + +describe('next config to webpack plugin config', () => { + const warnMock = jest.fn(); + const errorMock = jest.fn(); + + describe('includeDistDir', () => { + beforeAll(() => { + global.console.warn = warnMock; + global.console.error = errorMock; + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + + test.each([ + [{}, {}, {}], + [{}, { include: 'path' }, { include: 'path' }], + [{}, { include: [] }, { include: [] }], + [{}, { include: ['path'] }, { include: ['path'] }], + [{}, { include: { paths: ['path'] } }, { include: { paths: ['path'] } }], + ])('without `distDir`', (nextConfig, webpackPluginConfig, expectedConfig) => { + expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); + }); + + test.each([ + [{ distDir: 'test' }, {}, { include: 'test' }], + [{ distDir: 'test' }, { include: 'path' }, { include: ['path', 'test'] }], + [{ distDir: 'test' }, { include: [] }, { include: ['test'] }], + [{ distDir: 'test' }, { include: ['path'] }, { include: ['path', 'test'] }], + [{ distDir: 'test' }, { include: { paths: ['path'] } }, { include: { paths: ['path', 'test'] } }], + ])('with `distDir`, different paths', (nextConfig, webpackPluginConfig, expectedConfig) => { + expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); + }); + + test.each([ + [{ distDir: 'path' }, { include: 'path' }, { include: 'path' }], + [{ distDir: 'path' }, { include: ['path'] }, { include: ['path'] }], + [{ distDir: 'path' }, { include: { paths: ['path'] } }, { include: { paths: ['path'] } }], + ])('with `distDir`, same path', (nextConfig, webpackPluginConfig, expectedConfig) => { + expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); + }); + + test.each([ + [{ distDir: 'path' }, { include: {} }, { include: { paths: ['path'] } }], + [{ distDir: 'path' }, { include: { prop: 'val' } }, { include: { prop: 'val', paths: ['path'] } }], + ])('webpack plugin config as object with other prop', (nextConfig, webpackPluginConfig, expectedConfig) => { + // @ts-ignore Other props don't match types + expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); + expect(warnMock).toHaveBeenCalledTimes(1); + warnMock.mockClear(); + }); + + test.each([ + [{ distDir: 'path' }, { include: { paths: {} } }, { include: { paths: {} } }], + [{ distDir: 'path' }, { include: { paths: { badObject: true } } }, { include: { paths: { badObject: true } } }], + ])('webpack plugin config as object with bad structure', (nextConfig, webpackPluginConfig, expectedConfig) => { + // @ts-ignore Bad structures don't match types + expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); + expect(errorMock).toHaveBeenCalledTimes(1); + errorMock.mockClear(); + }); + }); +}); From 37e15ee91284a32d98d2f8cf0f66962388f5473c Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 14:16:49 +0200 Subject: [PATCH 05/16] Rename mocks --- .../nextConfigToWebpackPluginConfig.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts index b10aab4b2158..c2b961fe080c 100644 --- a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts +++ b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts @@ -1,13 +1,13 @@ import { includeDistDir } from '../../src/config/nextConfigToWebpackPluginConfig'; describe('next config to webpack plugin config', () => { - const warnMock = jest.fn(); - const errorMock = jest.fn(); - describe('includeDistDir', () => { + const consoleWarnMock = jest.fn(); + const consoleErrorMock = jest.fn(); + beforeAll(() => { - global.console.warn = warnMock; - global.console.error = errorMock; + global.console.warn = consoleWarnMock; + global.console.error = consoleErrorMock; }); afterAll(() => { @@ -48,8 +48,8 @@ describe('next config to webpack plugin config', () => { ])('webpack plugin config as object with other prop', (nextConfig, webpackPluginConfig, expectedConfig) => { // @ts-ignore Other props don't match types expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); - expect(warnMock).toHaveBeenCalledTimes(1); - warnMock.mockClear(); + expect(consoleWarnMock).toHaveBeenCalledTimes(1); + consoleWarnMock.mockClear(); }); test.each([ @@ -58,8 +58,8 @@ describe('next config to webpack plugin config', () => { ])('webpack plugin config as object with bad structure', (nextConfig, webpackPluginConfig, expectedConfig) => { // @ts-ignore Bad structures don't match types expect(includeDistDir(nextConfig, webpackPluginConfig)).toMatchObject(expectedConfig); - expect(errorMock).toHaveBeenCalledTimes(1); - errorMock.mockClear(); + expect(consoleErrorMock).toHaveBeenCalledTimes(1); + consoleErrorMock.mockClear(); }); }); }); From 9295eaa1c7835e2072dc6c8e7b90542288fc01b0 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Fri, 17 Sep 2021 16:55:02 +0200 Subject: [PATCH 06/16] fix types --- packages/nextjs/src/config/index.ts | 3 +-- .../src/config/nextConfigToWebpackPluginConfig.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index 59286741a5c5..9ea1ab3b4292 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -13,8 +13,6 @@ export function withSentryConfig( userNextConfig: ExportedNextConfig = {}, userSentryWebpackPluginOptions: Partial = {}, ): NextConfigFunction | NextConfigObject { - const webpackPluginOptionsWithSources = includeDistDir(userNextConfig, userSentryWebpackPluginOptions); - // 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') { @@ -31,6 +29,7 @@ export function withSentryConfig( }; } + const webpackPluginOptionsWithSources = includeDistDir(userNextConfig, userSentryWebpackPluginOptions); // Otherwise, we can just merge their config with ours and return an object. return { ...userNextConfig, diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index cb97a4bcf91e..ebf7516c23cb 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -1,4 +1,4 @@ -import { ExportedNextConfig, SentryWebpackPluginOptions } from './types'; +import { NextConfigObject, SentryWebpackPluginOptions } from './types'; /** * Creates a new Sentry Webpack Plugin config with the `distDir` option from Next.js config @@ -14,12 +14,13 @@ import { ExportedNextConfig, SentryWebpackPluginOptions } from './types'; * @returns New Sentry Webpack Plugin config */ export function includeDistDir( - nextConfig: ExportedNextConfig, + nextConfig: NextConfigObject, sentryWebpackPluginOptions: Partial, ): Partial { if (!nextConfig.distDir) { return { ...sentryWebpackPluginOptions }; } + // It's assumed `distDir` is a string as that's what Next.js is expecting. If it's not, Next.js itself will complain const usersInclude = sentryWebpackPluginOptions.include; let sourcesToInclude; @@ -28,11 +29,12 @@ export function includeDistDir( } else if (typeof usersInclude === 'string') { sourcesToInclude = usersInclude === nextConfig.distDir ? usersInclude : [usersInclude, nextConfig.distDir]; } else if (Array.isArray(usersInclude)) { + // @ts-ignore '__spreadArray' import from tslib, ts(2343) sourcesToInclude = [...new Set(usersInclude.concat(nextConfig.distDir))]; } else { // Object if (Array.isArray(usersInclude.paths)) { - const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir))]; + const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir as string))]; sourcesToInclude = { ...usersInclude, paths: uniquePaths }; } else if (typeof usersInclude.paths === 'undefined') { // eslint-disable-next-line no-console @@ -50,7 +52,8 @@ export function includeDistDir( 'See https://github.com/getsentry/sentry-webpack-plugin#optionsinclude', ); // Keep the same object even if it's incorrect, so that the user can get a more precise error from sentry-cli - sourcesToInclude = usersInclude; + // Casting to `any` for TS not complaining about it being `unknown` + sourcesToInclude = usersInclude as any; } } From 1a3aed0c3f0cee08c410fc1ccb1c6e642a92b345 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 11:12:04 +0200 Subject: [PATCH 07/16] Use `??` instead of `||` --- packages/nextjs/src/config/webpack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 5888b267b71a..2ea62ac17c0d 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -261,7 +261,7 @@ function getWebpackPluginOptions( userPluginOptions: Partial, ): SentryWebpackPluginOptions { const { isServer, dir: projectDir, buildId, dev: isDev, config: nextConfig, webpack } = buildContext; - const distDir = nextConfig.distDir || '.next'; // `.next` is the default directory + const distDir = nextConfig.distDir ?? '.next'; // `.next` is the default directory const isWebpack5 = webpack.version.startsWith('5'); const isServerless = nextConfig.target === 'experimental-serverless-trace'; From 344fd39160f266b51d5202b08e6ab4063a361e84 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 11:58:21 +0200 Subject: [PATCH 08/16] Add tests for `getWebpackPluginOptions` --- packages/nextjs/src/config/webpack.ts | 2 +- packages/nextjs/test/config.test.ts | 40 +++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 2ea62ac17c0d..748a98e75d67 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -256,7 +256,7 @@ function shouldAddSentryToEntryPoint(entryPointName: string): boolean { * @param userPluginOptions User-provided SentryWebpackPlugin options * @returns Final set of combined options */ -function getWebpackPluginOptions( +export function getWebpackPluginOptions( buildContext: BuildContext, userPluginOptions: Partial, ): SentryWebpackPluginOptions { diff --git a/packages/nextjs/test/config.test.ts b/packages/nextjs/test/config.test.ts index d395f43dcba5..94ed8e56e297 100644 --- a/packages/nextjs/test/config.test.ts +++ b/packages/nextjs/test/config.test.ts @@ -13,7 +13,12 @@ import { SentryWebpackPluginOptions, WebpackConfigObject, } from '../src/config/types'; -import { constructWebpackConfigFunction, getUserConfigFile, SentryWebpackPlugin } from '../src/config/webpack'; +import { + constructWebpackConfigFunction, + getUserConfigFile, + getWebpackPluginOptions, + SentryWebpackPlugin, +} from '../src/config/webpack'; const SERVER_SDK_CONFIG_FILE = 'sentry.server.config.js'; const CLIENT_SDK_CONFIG_FILE = 'sentry.client.config.js'; @@ -89,16 +94,21 @@ const clientWebpackConfig = { // In real life, next will copy the `userNextConfig` into the `buildContext`. Since we're providing mocks for both of // those, we need to mimic that behavior, and since `userNextConfig` can vary per test, we need to have the option do it // dynamically. -function getBuildContext(buildTarget: 'server' | 'client', userNextConfig: Partial): BuildContext { +function getBuildContext( + buildTarget: 'server' | 'client', + userNextConfig: Partial, + webpackVersion: string = '5.4.15', +): BuildContext { return { dev: false, buildId: 'sItStAyLiEdOwN', dir: '/Users/Maisey/projects/squirrelChasingSimulator', config: { target: 'server', ...userNextConfig }, - webpack: { version: '5.4.15' }, + webpack: { version: webpackVersion }, isServer: buildTarget === 'server', }; } + const serverBuildContext = getBuildContext('server', userNextConfig); const clientBuildContext = getBuildContext('client', userNextConfig); @@ -580,4 +590,28 @@ describe('Sentry webpack plugin config', () => { ); }); }); + + it.each([ + /** `distDir` is not defined */ + [getBuildContext('client', {}), '.next'], // client + [getBuildContext('server', { target: 'experimental-serverless-trace' }), '.next'], // serverless + [getBuildContext('server', {}, '4'), '.next'], // server, webpack < 5 + [getBuildContext('server', {}, '5'), '.next'], // server, webpack == 5 + + /** `distDir` is defined */ + [getBuildContext('client', { distDir: 'tmpDir' }), 'tmpDir'], // client + [getBuildContext('server', { distDir: 'tmpDir', target: 'experimental-serverless-trace' }), 'tmpDir'], // serverless + [getBuildContext('server', { distDir: 'tmpDir' }, '4'), 'tmpDir'], // server, webpack < 5 + [getBuildContext('server', { distDir: 'tmpDir' }, '5'), 'tmpDir'], // server, webpack == 5 + ])('correct paths from `distDir` in WebpackPluginOptions', (buildContext: BuildContext, expectedDistDir) => { + const includePaths = getWebpackPluginOptions(buildContext, { + /** userPluginOptions */ + }).include as { paths: [] }[]; + + for (const pathDescriptor of includePaths) { + for (const path of pathDescriptor.paths) { + expect(path).toMatch(new RegExp(`^${expectedDistDir}.*`)); + } + } + }); }); From a940c07fc1ef5e01a472db7f0809b412e6f612aa Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 12:08:39 +0200 Subject: [PATCH 09/16] Remove redundant comments --- packages/nextjs/test/config.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/nextjs/test/config.test.ts b/packages/nextjs/test/config.test.ts index 94ed8e56e297..952762c3ab59 100644 --- a/packages/nextjs/test/config.test.ts +++ b/packages/nextjs/test/config.test.ts @@ -593,16 +593,16 @@ describe('Sentry webpack plugin config', () => { it.each([ /** `distDir` is not defined */ - [getBuildContext('client', {}), '.next'], // client + [getBuildContext('client', {}), '.next'], [getBuildContext('server', { target: 'experimental-serverless-trace' }), '.next'], // serverless - [getBuildContext('server', {}, '4'), '.next'], // server, webpack < 5 - [getBuildContext('server', {}, '5'), '.next'], // server, webpack == 5 + [getBuildContext('server', {}, '4'), '.next'], + [getBuildContext('server', {}, '5'), '.next'], /** `distDir` is defined */ - [getBuildContext('client', { distDir: 'tmpDir' }), 'tmpDir'], // client + [getBuildContext('client', { distDir: 'tmpDir' }), 'tmpDir'], [getBuildContext('server', { distDir: 'tmpDir', target: 'experimental-serverless-trace' }), 'tmpDir'], // serverless - [getBuildContext('server', { distDir: 'tmpDir' }, '4'), 'tmpDir'], // server, webpack < 5 - [getBuildContext('server', { distDir: 'tmpDir' }, '5'), 'tmpDir'], // server, webpack == 5 + [getBuildContext('server', { distDir: 'tmpDir' }, '4'), 'tmpDir'], + [getBuildContext('server', { distDir: 'tmpDir' }, '5'), 'tmpDir'], ])('correct paths from `distDir` in WebpackPluginOptions', (buildContext: BuildContext, expectedDistDir) => { const includePaths = getWebpackPluginOptions(buildContext, { /** userPluginOptions */ From f5f1f25841b17e49da7bdf54f60d39ecd1477a7c Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 15:31:11 +0200 Subject: [PATCH 10/16] Separate tests by test name --- packages/nextjs/test/config.test.ts | 54 ++++++++++++++++++----------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/nextjs/test/config.test.ts b/packages/nextjs/test/config.test.ts index 952762c3ab59..8343a9053cc3 100644 --- a/packages/nextjs/test/config.test.ts +++ b/packages/nextjs/test/config.test.ts @@ -591,27 +591,39 @@ describe('Sentry webpack plugin config', () => { }); }); - it.each([ - /** `distDir` is not defined */ - [getBuildContext('client', {}), '.next'], - [getBuildContext('server', { target: 'experimental-serverless-trace' }), '.next'], // serverless - [getBuildContext('server', {}, '4'), '.next'], - [getBuildContext('server', {}, '5'), '.next'], - - /** `distDir` is defined */ - [getBuildContext('client', { distDir: 'tmpDir' }), 'tmpDir'], - [getBuildContext('server', { distDir: 'tmpDir', target: 'experimental-serverless-trace' }), 'tmpDir'], // serverless - [getBuildContext('server', { distDir: 'tmpDir' }, '4'), 'tmpDir'], - [getBuildContext('server', { distDir: 'tmpDir' }, '5'), 'tmpDir'], - ])('correct paths from `distDir` in WebpackPluginOptions', (buildContext: BuildContext, expectedDistDir) => { - const includePaths = getWebpackPluginOptions(buildContext, { - /** userPluginOptions */ - }).include as { paths: [] }[]; - - for (const pathDescriptor of includePaths) { - for (const path of pathDescriptor.paths) { - expect(path).toMatch(new RegExp(`^${expectedDistDir}.*`)); + describe('correct paths from `distDir` in WebpackPluginOptions', () => { + it.each([ + [getBuildContext('client', {}), '.next'], + [getBuildContext('server', { target: 'experimental-serverless-trace' }), '.next'], // serverless + [getBuildContext('server', {}, '4'), '.next'], + [getBuildContext('server', {}, '5'), '.next'], + ])('`distDir` is not defined', (buildContext: BuildContext, expectedDistDir) => { + const includePaths = getWebpackPluginOptions(buildContext, { + /** userPluginOptions */ + }).include as { paths: [] }[]; + + for (const pathDescriptor of includePaths) { + for (const path of pathDescriptor.paths) { + expect(path).toMatch(new RegExp(`^${expectedDistDir}.*`)); + } } - } + }); + + it.each([ + [getBuildContext('client', { distDir: 'tmpDir' }), 'tmpDir'], + [getBuildContext('server', { distDir: 'tmpDir', target: 'experimental-serverless-trace' }), 'tmpDir'], // serverless + [getBuildContext('server', { distDir: 'tmpDir' }, '4'), 'tmpDir'], + [getBuildContext('server', { distDir: 'tmpDir' }, '5'), 'tmpDir'], + ])('`distDir` is defined', (buildContext: BuildContext, expectedDistDir) => { + const includePaths = getWebpackPluginOptions(buildContext, { + /** userPluginOptions */ + }).include as { paths: [] }[]; + + for (const pathDescriptor of includePaths) { + for (const path of pathDescriptor.paths) { + expect(path).toMatch(new RegExp(`^${expectedDistDir}.*`)); + } + } + }); }); }); From ef4cffde5da98183cd4e63f4df640cc20d5e3ccf Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:18:20 +0200 Subject: [PATCH 11/16] Generalize the use case --- packages/nextjs/src/config/index.ts | 6 +- .../config/nextConfigToWebpackPluginConfig.ts | 66 +++++++++++++++++++ .../nextConfigToWebpackPluginConfig.test.ts | 39 ++++++++++- 3 files changed, 107 insertions(+), 4 deletions(-) diff --git a/packages/nextjs/src/config/index.ts b/packages/nextjs/src/config/index.ts index 9ea1ab3b4292..5622f0055511 100644 --- a/packages/nextjs/src/config/index.ts +++ b/packages/nextjs/src/config/index.ts @@ -1,4 +1,4 @@ -import { includeDistDir } from './nextConfigToWebpackPluginConfig'; +import includeAllNextjsProps from './nextConfigToWebpackPluginConfig'; import { ExportedNextConfig, NextConfigFunction, NextConfigObject, SentryWebpackPluginOptions } from './types'; import { constructWebpackConfigFunction } from './webpack'; @@ -18,7 +18,7 @@ export function withSentryConfig( if (typeof userNextConfig === 'function') { return function(phase: string, defaults: { defaultConfig: NextConfigObject }): NextConfigObject { const materializedUserNextConfig = userNextConfig(phase, defaults); - const sentryWebpackPluginOptionsWithSources = includeDistDir( + const sentryWebpackPluginOptionsWithSources = includeAllNextjsProps( materializedUserNextConfig, userSentryWebpackPluginOptions, ); @@ -29,7 +29,7 @@ export function withSentryConfig( }; } - const webpackPluginOptionsWithSources = includeDistDir(userNextConfig, userSentryWebpackPluginOptions); + const webpackPluginOptionsWithSources = includeAllNextjsProps(userNextConfig, userSentryWebpackPluginOptions); // Otherwise, we can just merge their config with ours and return an object. return { ...userNextConfig, diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index ebf7516c23cb..a7016d1a0990 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -1,5 +1,71 @@ import { NextConfigObject, SentryWebpackPluginOptions } from './types'; +/** + * About types: + * It's not possible to set strong types because they end up forcing you to explicitly + * set `undefined` for properties you don't want to include, which is quite + * inconvenient. The workaround to this is to relax type requirements at some point, + * which means not enforcing types (why have strong typing then?) and still having code + * that is hard to read. + */ + +/** + * Next.js properties that should modify the webpack plugin properties. + * They should have an includer function in the map. + */ +export const SUPPORTED_NEXTJS_PROPERTIES = ['distDir']; + +type PropIncluderFn = ( + nextConfig: NextConfigObject, + sentryWebpackPluginOptions: Partial, +) => Partial; + +export type PropsIncluderMapType = Record; +export const PROPS_INCLUDER_MAP: PropsIncluderMapType = { + distDir: includeDistDir, +}; + +/** + * Creates a new Sentry Webpack Plugin config from the given one, including all available + * properties in the Nextjs Config. + * + * @param nextConfig User's Next.js config. + * @param sentryWebpackPluginOptions User's Sentry Webpack Plugin config. + * @returns New Sentry Webpack Plugin Config. + */ +export default function includeAllNextjsProps( + nextConfig: NextConfigObject, + sentryWebpackPluginOptions: Partial, +): Partial { + return includeNextjsProps(nextConfig, sentryWebpackPluginOptions, PROPS_INCLUDER_MAP, SUPPORTED_NEXTJS_PROPERTIES); +} + +/** + * Creates a new Sentry Webpack Plugin config from the given one, and applying the corresponding + * modifications to the given next properties. + * + * @param nextConfig User's Next.js config. + * @param sentryWebpackPluginOptions User's Sentry Webapck Plugin config. + * @param nextProps Next.js config's properties that should modify webpack plugin properties. + * @returns New Sentry Webpack Plugin config. + */ +export function includeNextjsProps( + nextConfig: NextConfigObject, + sentryWebpackPluginOptions: Partial, + propsIncluderMap: Record, + nextProps: string[], +): Partial { + // @ts-ignore '__spreadArray' import from tslib, ts(2343) + const propsToInclude = [...new Set(nextProps)]; + return ( + propsToInclude + // Types are not strict enought to ensure there's a function in the map + .filter(prop => propsIncluderMap[prop]) + .map(prop => propsIncluderMap[prop](nextConfig, sentryWebpackPluginOptions)) + .reduce((prev, current) => ({ ...prev, ...current }), {}) + ); +} + /** * Creates a new Sentry Webpack Plugin config with the `distDir` option from Next.js config * in the `include` property. diff --git a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts index c2b961fe080c..90225a1443f9 100644 --- a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts +++ b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts @@ -1,4 +1,41 @@ -import { includeDistDir } from '../../src/config/nextConfigToWebpackPluginConfig'; +import includeAllNextjsProps, { + includeDistDir, + includeNextjsProps, + PropsIncluderMapType, +} from '../../src/config/nextConfigToWebpackPluginConfig'; +import { SentryWebpackPluginOptions } from '../../src/config/types'; + +test('includeAllNextjsProps', () => { + expect(includeAllNextjsProps({ distDir: 'test' }, {})).toMatchObject({ include: 'test' }); +}); + +describe('includeNextjsProps', () => { + const includerMap: PropsIncluderMapType = { + test: includeEverythingFn, + }; + const includeEverything = { + include: 'everything', + }; + function includeEverythingFn(): Partial { + return includeEverything; + } + + test('a prop and an includer', () => { + expect(includeNextjsProps({ test: true }, {}, includerMap, ['test'])).toMatchObject(includeEverything); + }); + + test('a prop without includer', () => { + expect(includeNextjsProps({ noExist: false }, {}, includerMap, ['noExist'])).toMatchObject({}); + }); + + test('an includer without a prop', () => { + expect(includeNextjsProps({ noExist: false }, {}, includerMap, ['test'])).toMatchObject({}); + }); + + test('neither prop nor includer', () => { + expect(includeNextjsProps({}, {}, {}, [])).toMatchObject({}); + }); +}); describe('next config to webpack plugin config', () => { describe('includeDistDir', () => { From 3120b7c43eb11a2e034a2fefe0f2feabd2a30316 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:26:22 +0200 Subject: [PATCH 12/16] Add note about overriding values --- packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index a7016d1a0990..7c3cefa5fc58 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -42,7 +42,8 @@ export default function includeAllNextjsProps( /** * Creates a new Sentry Webpack Plugin config from the given one, and applying the corresponding - * modifications to the given next properties. + * modifications to the given next properties. If more than one option generates the same + * properties, the values generated last will override previous ones. * * @param nextConfig User's Next.js config. * @param sentryWebpackPluginOptions User's Sentry Webapck Plugin config. From de8ff3e89497893fb6367433ec8e3a268f74b454 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Tue, 21 Sep 2021 14:53:46 +0200 Subject: [PATCH 13/16] Add test for duplicated props in includeNextjsProps --- .../nextConfigToWebpackPluginConfig.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts index 90225a1443f9..c919eb338280 100644 --- a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts +++ b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts @@ -35,6 +35,21 @@ describe('includeNextjsProps', () => { test('neither prop nor includer', () => { expect(includeNextjsProps({}, {}, {}, [])).toMatchObject({}); }); + + test('duplicated props', () => { + let counter: number = 0; + const mock = jest.fn().mockImplementation(() => { + const current = counter; + counter += 1; + return { call: current }; + }); + const map: PropsIncluderMapType = { + dup: mock, + }; + + expect(includeNextjsProps({}, {}, map, ['dup', 'dup'])).toMatchObject({ call: 0 }); + expect(mock).toHaveBeenCalledTimes(1); + }); }); describe('next config to webpack plugin config', () => { From ca0a409960f941a08233a4a467752e1b995f1180 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:46:57 +0200 Subject: [PATCH 14/16] feedback --- .../src/config/nextConfigToWebpackPluginConfig.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index 7c3cefa5fc58..225f365ece3e 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -20,8 +20,7 @@ type PropIncluderFn = ( sentryWebpackPluginOptions: Partial, ) => Partial; -export type PropsIncluderMapType = Record; -export const PROPS_INCLUDER_MAP: PropsIncluderMapType = { +export const PROPS_INCLUDER_MAP: Record = { distDir: includeDistDir, }; @@ -69,23 +68,23 @@ export function includeNextjsProps( /** * Creates a new Sentry Webpack Plugin config with the `distDir` option from Next.js config - * in the `include` property. + * in the `include` property, if `distDir` is provided. * - * If no `distDir` is provided, the Webpack Plugin config doesn't change. + * If no `distDir` is provided, the Webpack Plugin config doesn't change and the same object is returned. * If no `include` has been defined defined, the `distDir` value is assigned. * The `distDir` directory is merged to the directories in `include`, if defined. * Duplicated paths are removed while merging. * * @param nextConfig User's Next.js config * @param sentryWebpackPluginOptions User's Sentry Webpack Plugin config - * @returns New Sentry Webpack Plugin config + * @returns Sentry Webpack Plugin config */ export function includeDistDir( nextConfig: NextConfigObject, sentryWebpackPluginOptions: Partial, ): Partial { if (!nextConfig.distDir) { - return { ...sentryWebpackPluginOptions }; + return sentryWebpackPluginOptions; } // It's assumed `distDir` is a string as that's what Next.js is expecting. If it's not, Next.js itself will complain const usersInclude = sentryWebpackPluginOptions.include; @@ -96,8 +95,7 @@ export function includeDistDir( } else if (typeof usersInclude === 'string') { sourcesToInclude = usersInclude === nextConfig.distDir ? usersInclude : [usersInclude, nextConfig.distDir]; } else if (Array.isArray(usersInclude)) { - // @ts-ignore '__spreadArray' import from tslib, ts(2343) - sourcesToInclude = [...new Set(usersInclude.concat(nextConfig.distDir))]; + sourcesToInclude = Array.from(new Set(usersInclude.concat(nextConfig.distDir as string))); } else { // Object if (Array.isArray(usersInclude.paths)) { From 3f1df7c4a621ed40e1625be1c6d4f080866db6dc Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:51:56 +0200 Subject: [PATCH 15/16] Use `Array.from` instead of spread array --- .../nextjs/src/config/nextConfigToWebpackPluginConfig.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index 225f365ece3e..02b7a412560a 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -55,8 +55,7 @@ export function includeNextjsProps( propsIncluderMap: Record, nextProps: string[], ): Partial { - // @ts-ignore '__spreadArray' import from tslib, ts(2343) - const propsToInclude = [...new Set(nextProps)]; + const propsToInclude = Array.from(new Set(nextProps)); return ( propsToInclude // Types are not strict enought to ensure there's a function in the map @@ -99,7 +98,7 @@ export function includeDistDir( } else { // Object if (Array.isArray(usersInclude.paths)) { - const uniquePaths = [...new Set(usersInclude.paths.concat(nextConfig.distDir as string))]; + const uniquePaths = Array.from(new Set(usersInclude.paths.concat(nextConfig.distDir as string))); sourcesToInclude = { ...usersInclude, paths: uniquePaths }; } else if (typeof usersInclude.paths === 'undefined') { // eslint-disable-next-line no-console From 3ee121595922b65d714e8a5342fdd49eac95f466 Mon Sep 17 00:00:00 2001 From: iker barriocanal <32816711+iker-barriocanal@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:54:20 +0200 Subject: [PATCH 16/16] Fix type on test --- .../nextjs/src/config/nextConfigToWebpackPluginConfig.ts | 2 +- .../test/config/nextConfigToWebpackPluginConfig.test.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts index 02b7a412560a..89b8e00bf94f 100644 --- a/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts +++ b/packages/nextjs/src/config/nextConfigToWebpackPluginConfig.ts @@ -15,7 +15,7 @@ import { NextConfigObject, SentryWebpackPluginOptions } from './types'; */ export const SUPPORTED_NEXTJS_PROPERTIES = ['distDir']; -type PropIncluderFn = ( +export type PropIncluderFn = ( nextConfig: NextConfigObject, sentryWebpackPluginOptions: Partial, ) => Partial; diff --git a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts index c919eb338280..6d359934b464 100644 --- a/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts +++ b/packages/nextjs/test/config/nextConfigToWebpackPluginConfig.test.ts @@ -1,7 +1,7 @@ import includeAllNextjsProps, { includeDistDir, includeNextjsProps, - PropsIncluderMapType, + PropIncluderFn, } from '../../src/config/nextConfigToWebpackPluginConfig'; import { SentryWebpackPluginOptions } from '../../src/config/types'; @@ -10,7 +10,7 @@ test('includeAllNextjsProps', () => { }); describe('includeNextjsProps', () => { - const includerMap: PropsIncluderMapType = { + const includerMap: Record = { test: includeEverythingFn, }; const includeEverything = { @@ -43,7 +43,7 @@ describe('includeNextjsProps', () => { counter += 1; return { call: current }; }); - const map: PropsIncluderMapType = { + const map: Record = { dup: mock, };