From 56a139166275fa45748920f813ba3e8c5a3ff9fb Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 9 Dec 2022 11:48:14 +0000 Subject: [PATCH 1/6] ref(nextjs): Use generic loader to inject global values --- packages/nextjs/rollup.npm.config.js | 3 - packages/nextjs/src/config/loaders/index.ts | 1 + .../config/loaders/valueInjectionLoader.ts | 26 ++++ ...clientRewriteFramesPrefixLoaderTemplate.ts | 9 -- .../templates/releasePrefixLoaderTemplate.ts | 16 --- ...serverRewriteFramesPrefixLoaderTemplate.ts | 6 - packages/nextjs/src/config/webpack.ts | 132 ++++++++++-------- packages/nextjs/src/index.client.ts | 7 +- packages/nextjs/src/index.server.ts | 7 +- packages/nextjs/test/config/loaders.test.ts | 52 ++----- 10 files changed, 124 insertions(+), 135 deletions(-) create mode 100644 packages/nextjs/src/config/loaders/valueInjectionLoader.ts delete mode 100644 packages/nextjs/src/config/templates/clientRewriteFramesPrefixLoaderTemplate.ts delete mode 100644 packages/nextjs/src/config/templates/releasePrefixLoaderTemplate.ts delete mode 100644 packages/nextjs/src/config/templates/serverRewriteFramesPrefixLoaderTemplate.ts diff --git a/packages/nextjs/rollup.npm.config.js b/packages/nextjs/rollup.npm.config.js index e6ddcbf97a50..32100ef278be 100644 --- a/packages/nextjs/rollup.npm.config.js +++ b/packages/nextjs/rollup.npm.config.js @@ -20,9 +20,6 @@ export default [ ...makeNPMConfigVariants( makeBaseNPMConfig({ entrypoints: [ - 'src/config/templates/serverRewriteFramesPrefixLoaderTemplate.ts', - 'src/config/templates/clientRewriteFramesPrefixLoaderTemplate.ts', - 'src/config/templates/releasePrefixLoaderTemplate.ts', 'src/config/templates/pageProxyLoaderTemplate.ts', 'src/config/templates/apiProxyLoaderTemplate.ts', ], diff --git a/packages/nextjs/src/config/loaders/index.ts b/packages/nextjs/src/config/loaders/index.ts index 00bf268fdc91..150e00bf1ca4 100644 --- a/packages/nextjs/src/config/loaders/index.ts +++ b/packages/nextjs/src/config/loaders/index.ts @@ -1,2 +1,3 @@ +export { default as valueInjectionLoader } from './valueInjectionLoader'; export { default as prefixLoader } from './prefixLoader'; export { default as proxyLoader } from './proxyLoader'; diff --git a/packages/nextjs/src/config/loaders/valueInjectionLoader.ts b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts new file mode 100644 index 000000000000..fbdae367cdaa --- /dev/null +++ b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts @@ -0,0 +1,26 @@ +import { LoaderThis } from './types'; + +type LoaderOptions = { + values: Record; +}; + +/** + * Set values on the global/window object at the start of a module. + * + * Options: + * - `values`: A record where the keys correspond to the keys of the global values to set and the values + * correspond to the values of the values on the global object. Values must be JSON serializable. + */ +export default function valueInjectionLoader(this: LoaderThis, userCode: string): string { + // We know one or the other will be defined, depending on the version of webpack being used + const { values } = 'getOptions' in this ? this.getOptions() : this.query; + + // Define some global proxy that works on server and on the browser. + let injectedCode = 'var _sentryCollisionFreeGlobalObject = typeof window === "undefined" ? global : window;\n'; + + Object.entries(values).forEach(([key, value]) => { + injectedCode += `_sentryCollisionFreeGlobalObject.${key} = ${JSON.stringify(value)};\n`; + }); + + return `${injectedCode}\n${userCode}`; +} diff --git a/packages/nextjs/src/config/templates/clientRewriteFramesPrefixLoaderTemplate.ts b/packages/nextjs/src/config/templates/clientRewriteFramesPrefixLoaderTemplate.ts deleted file mode 100644 index 50a304ae0586..000000000000 --- a/packages/nextjs/src/config/templates/clientRewriteFramesPrefixLoaderTemplate.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* eslint-disable no-restricted-globals */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - -(window as any).__rewriteFramesAssetPrefixPath__ = '__ASSET_PREFIX_PATH__'; - -// We need this to make this file an ESM module, which TS requires when using `isolatedModules`, but it doesn't affect -// the end result - Rollup recognizes that it's a no-op and doesn't include it when building our code. -export {}; diff --git a/packages/nextjs/src/config/templates/releasePrefixLoaderTemplate.ts b/packages/nextjs/src/config/templates/releasePrefixLoaderTemplate.ts deleted file mode 100644 index a41fe7f0d7c6..000000000000 --- a/packages/nextjs/src/config/templates/releasePrefixLoaderTemplate.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable no-constant-condition */ - -import { GLOBAL_OBJ } from '@sentry/utils'; - -import { EnhancedGlobal } from '../types'; - -const globalObj = GLOBAL_OBJ as EnhancedGlobal; - -globalObj.SENTRY_RELEASE = { id: '__RELEASE__' }; - -// Enable module federation support (see https://github.com/getsentry/sentry-webpack-plugin/pull/307) -if ('__PROJECT__') { - const key = '__ORG__' ? '__PROJECT__@__ORG__' : '__PROJECT__'; - globalObj.SENTRY_RELEASES = globalObj.SENTRY_RELEASES || {}; - globalObj.SENTRY_RELEASES[key] = { id: '__RELEASE__' }; -} diff --git a/packages/nextjs/src/config/templates/serverRewriteFramesPrefixLoaderTemplate.ts b/packages/nextjs/src/config/templates/serverRewriteFramesPrefixLoaderTemplate.ts deleted file mode 100644 index 9bce6accc6be..000000000000 --- a/packages/nextjs/src/config/templates/serverRewriteFramesPrefixLoaderTemplate.ts +++ /dev/null @@ -1,6 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any -(global as any).__rewriteFramesDistDir__ = '__DIST_DIR__'; - -// We need this to make this file an ESM module, which TS requires when using `isolatedModules`, but it doesn't affect -// the end result - Rollup recognizes that it's a no-op and doesn't include it when building our code. -export {}; diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index d2fec9898d27..186827df9fac 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -87,26 +87,8 @@ export function constructWebpackConfigFunction( // `newConfig.module.rules` is required, so we don't have to keep asserting its existence const newConfig = setUpModuleRules(rawNewConfig); - // Add a loader which will inject code that sets global values for use by `RewriteFrames` - addRewriteFramesLoader(newConfig, isServer ? 'server' : 'client', userNextConfig); - - newConfig.module.rules.push({ - test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, - use: [ - { - // Inject the release value the same way the webpack plugin does. - loader: path.resolve(__dirname, 'loaders/prefixLoader.js'), - options: { - templatePrefix: 'release', - replacements: [ - ['__RELEASE__', webpackPluginOptions.release || process.env.SENTRY_RELEASE], - ['__ORG__', webpackPluginOptions.org || process.env.SENTRY_ORG], - ['__PROJECT__', webpackPluginOptions.project || process.env.SENTRY_PROJECT || ''], - ], - }, - }, - ], - }); + // Add a loader which will inject code that sets global values + addValueInjectionLoader(newConfig, userNextConfig, webpackPluginOptions); if (isServer) { if (userSentryOptions.autoInstrumentServerFunctions !== false) { @@ -667,49 +649,85 @@ function setUpModuleRules(newConfig: WebpackConfigObject): WebpackConfigObjectWi } /** - * Support the `distDir` and `assetPrefix` options by making their values (easy to get here at build-time) available at - * runtime (for use by `RewriteFrames`), by injecting code to attach their values to `global` or `window`. - * - * @param newConfig The webpack config object being constructed - * @param target Either 'server' or 'client' - * @param userNextConfig The user's nextjs config options + * Adds loaders to inject values on the global object based on user configuration. */ -function addRewriteFramesLoader( +function addValueInjectionLoader( newConfig: WebpackConfigObjectWithModuleRules, - target: 'server' | 'client', userNextConfig: NextConfigObject, + webpackPluginOptions: SentryWebpackPlugin.SentryCliPluginOptions, ): void { - // Nextjs will use `basePath` in place of `assetPrefix` if it's defined but `assetPrefix` is not const assetPrefix = userNextConfig.assetPrefix || userNextConfig.basePath || ''; - const replacements = { - server: [ - [ - '__DIST_DIR__', - // Make sure that if we have a windows path, the backslashes are interpreted as such (rather than as escape - // characters) - userNextConfig.distDir?.replace(/\\/g, '\\\\') || '.next', - ], - ], - client: [ - [ - '__ASSET_PREFIX_PATH__', - // Get the path part of `assetPrefix`, minus any trailing slash. (We use a placeholder for the origin if - // `assetPreix` doesn't include one. Since we only care about the path, it doesn't matter what it is.) - assetPrefix ? new URL(assetPrefix, 'http://dogs.are.great').pathname.replace(/\/$/, '') : '', - ], - ], + const releaseValue = webpackPluginOptions.release || process.env.SENTRY_RELEASE; + const orgValue = webpackPluginOptions.org || process.env.SENTRY_ORG; + const projectValue = webpackPluginOptions.project || process.env.SENTRY_PROJECT; + + const serverValues = { + // Make sure that if we have a windows path, the backslashes are interpreted as such (rather than as escape + // characters) + __rewriteFramesDistDir__: userNextConfig.distDir?.replace(/\\/g, '\\\\') || '.next', + }; + + const clientValues = { + // Get the path part of `assetPrefix`, minus any trailing slash. (We use a placeholder for the origin if + // `assetPreix` doesn't include one. Since we only care about the path, it doesn't matter what it is.) + __rewriteFramesAssetPrefixPath__: assetPrefix + ? new URL(assetPrefix, 'http://dogs.are.great').pathname.replace(/\/$/, '') + : '', + }; + + const isomorphicValues = { + // Inject release into SDK + ...(releaseValue + ? { + SENTRY_RELEASE: { + id: releaseValue, + }, + } + : undefined), + + // Enable module federation support (see https://github.com/getsentry/sentry-webpack-plugin/pull/307) + ...(projectValue && releaseValue + ? { + SENTRY_RELEASES: { + [orgValue ? `${projectValue}@${orgValue}` : projectValue]: { id: releaseValue }, + }, + } + : undefined), }; - newConfig.module.rules.push({ - test: new RegExp(`sentry\\.${target}\\.config\\.(jsx?|tsx?)`), - use: [ - { - loader: path.resolve(__dirname, 'loaders/prefixLoader.js'), - options: { - templatePrefix: `${target}RewriteFrames`, - replacements: replacements[target], + newConfig.module.rules.push( + { + test: /sentry\.server\.config\.(jsx?|tsx?)/, + use: [ + { + loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'), + options: { + values: serverValues, + }, }, - }, - ], - }); + ], + }, + { + test: /sentry\.client\.config\.(jsx?|tsx?)/, + use: [ + { + loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'), + options: { + values: clientValues, + }, + }, + ], + }, + { + test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, + use: [ + { + loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'), + options: { + values: isomorphicValues, + }, + }, + ], + }, + ); } diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index a28969824c92..7a8eaa1179db 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -35,7 +35,10 @@ declare const __SENTRY_TRACING__: boolean; // https://github.com/vercel/next.js/blob/166e5fb9b92f64c4b5d1f6560a05e2b9778c16fb/packages/next/build/webpack-config.ts#L206 declare const EdgeRuntime: string | undefined; -type GlobalWithAssetPrefixPath = typeof global & { __rewriteFramesAssetPrefixPath__: string }; +const globalWithInjectedValues = global as typeof global & { + __rewriteFramesAssetPrefixPath__: string; + __sentryRewritesTunnelPath__?: string; +}; /** Inits the Sentry NextJS SDK on the browser with the React SDK. */ export function init(options: NextjsOptions): void { @@ -67,7 +70,7 @@ function addClientIntegrations(options: NextjsOptions): void { // This value is injected at build time, based on the output directory specified in the build config. Though a default // is set there, we set it here as well, just in case something has gone wrong with the injection. - const assetPrefixPath = (global as GlobalWithAssetPrefixPath).__rewriteFramesAssetPrefixPath__ || ''; + const assetPrefixPath = globalWithInjectedValues.__rewriteFramesAssetPrefixPath__ || ''; const defaultRewriteFramesIntegration = new RewriteFrames({ // Turn `//_next/static/...` into `app:///_next/static/...` diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index 993abbd4cdb8..ca36e41a0427 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -19,7 +19,10 @@ export { captureUnderscoreErrorException } from './utils/_error'; // because or SSR of next.js we can only use this. export { ErrorBoundary, showReportDialog, withErrorBoundary } from '@sentry/react'; -type GlobalWithDistDir = typeof global & { __rewriteFramesDistDir__: string }; +const globalWithInjectedValues = global as typeof global & { + __rewriteFramesDistDir__: string; +}; + const domain = domainModule as typeof domainModule & { active: (domainModule.Domain & Carrier) | null }; // This is a variable that Next.js will string replace during build with a string if run in an edge runtime from Next.js @@ -114,7 +117,7 @@ function addServerIntegrations(options: NextjsOptions): void { // This value is injected at build time, based on the output directory specified in the build config. Though a default // is set there, we set it here as well, just in case something has gone wrong with the injection. - const distDirName = (global as GlobalWithDistDir).__rewriteFramesDistDir__ || '.next'; + const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__ || '.next'; // nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so // we can read in the project directory from the currently running process const distDirAbsPath = path.resolve(process.cwd(), distDirName); diff --git a/packages/nextjs/test/config/loaders.test.ts b/packages/nextjs/test/config/loaders.test.ts index 26b3d039ec15..4053f1d90457 100644 --- a/packages/nextjs/test/config/loaders.test.ts +++ b/packages/nextjs/test/config/loaders.test.ts @@ -41,7 +41,7 @@ declare global { describe('webpack loaders', () => { describe('server loaders', () => { - it('adds server `RewriteFrames` loader to server config', async () => { + it('adds server `valueInjection` loader to server config', async () => { const finalWebpackConfig = await materializeFinalWebpackConfig({ exportedNextConfig, incomingWebpackConfig: serverWebpackConfig, @@ -52,34 +52,8 @@ describe('webpack loaders', () => { test: /sentry\.server\.config\.(jsx?|tsx?)/, use: [ { - loader: expect.stringEndingWith('prefixLoader.js'), - options: expect.objectContaining({ templatePrefix: 'serverRewriteFrames' }), - }, - ], - }); - }); - - it('adds release prefix loader to server config', async () => { - const finalWebpackConfig = await materializeFinalWebpackConfig({ - exportedNextConfig, - incomingWebpackConfig: serverWebpackConfig, - incomingWebpackBuildContext: serverBuildContext, - userSentryWebpackPluginConfig: userSentryWebpackPluginConfig, - }); - - expect(finalWebpackConfig.module.rules).toContainEqual({ - test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, - use: [ - { - loader: expect.stringEndingWith('prefixLoader.js'), - options: { - templatePrefix: 'release', - replacements: [ - ['__RELEASE__', 'doGsaREgReaT'], - ['__ORG__', 'squirrelChasers'], - ['__PROJECT__', 'simulator'], - ], - }, + loader: expect.stringEndingWith('valueInjectionLoader.js'), + options: expect.objectContaining({ values: expect.objectContaining({}) }), }, ], }); @@ -87,7 +61,7 @@ describe('webpack loaders', () => { }); describe('client loaders', () => { - it('adds `RewriteFrames` loader to client config', async () => { + it('adds `valueInjection` loader to client config', async () => { const finalWebpackConfig = await materializeFinalWebpackConfig({ exportedNextConfig, incomingWebpackConfig: clientWebpackConfig, @@ -98,14 +72,14 @@ describe('webpack loaders', () => { test: /sentry\.client\.config\.(jsx?|tsx?)/, use: [ { - loader: expect.stringEndingWith('prefixLoader.js'), - options: expect.objectContaining({ templatePrefix: 'clientRewriteFrames' }), + loader: expect.stringEndingWith('valueInjectionLoader.js'), + options: expect.objectContaining({ values: expect.objectContaining({}) }), }, ], }); }); - it('adds release prefix loader to client config', async () => { + it('adds `valueInjection` loader with release values to client and server configs', async () => { const finalWebpackConfig = await materializeFinalWebpackConfig({ exportedNextConfig, incomingWebpackConfig: clientWebpackConfig, @@ -117,14 +91,12 @@ describe('webpack loaders', () => { test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, use: [ { - loader: expect.stringEndingWith('prefixLoader.js'), + loader: expect.stringEndingWith('valueInjectionLoader.js'), options: { - templatePrefix: 'release', - replacements: [ - ['__RELEASE__', 'doGsaREgReaT'], - ['__ORG__', 'squirrelChasers'], - ['__PROJECT__', 'simulator'], - ], + values: { + SENTRY_RELEASE: { id: 'doGsaREgReaT' }, + SENTRY_RELEASES: { 'simulator@squirrelChasers': { id: 'doGsaREgReaT' } }, + }, }, }, ], From b499fef0a59bff0de1c1c09a68a67236900d7c11 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 12 Dec 2022 07:35:28 +0000 Subject: [PATCH 2/6] Simplify isomorphic loader logic --- packages/nextjs/src/config/webpack.ts | 41 +++++++++++---------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 186827df9fac..22738dcfdc90 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -661,20 +661,6 @@ function addValueInjectionLoader( const orgValue = webpackPluginOptions.org || process.env.SENTRY_ORG; const projectValue = webpackPluginOptions.project || process.env.SENTRY_PROJECT; - const serverValues = { - // Make sure that if we have a windows path, the backslashes are interpreted as such (rather than as escape - // characters) - __rewriteFramesDistDir__: userNextConfig.distDir?.replace(/\\/g, '\\\\') || '.next', - }; - - const clientValues = { - // Get the path part of `assetPrefix`, minus any trailing slash. (We use a placeholder for the origin if - // `assetPreix` doesn't include one. Since we only care about the path, it doesn't matter what it is.) - __rewriteFramesAssetPrefixPath__: assetPrefix - ? new URL(assetPrefix, 'http://dogs.are.great').pathname.replace(/\/$/, '') - : '', - }; - const isomorphicValues = { // Inject release into SDK ...(releaseValue @@ -695,6 +681,22 @@ function addValueInjectionLoader( : undefined), }; + const serverValues = { + ...isomorphicValues, + // Make sure that if we have a windows path, the backslashes are interpreted as such (rather than as escape + // characters) + __rewriteFramesDistDir__: userNextConfig.distDir?.replace(/\\/g, '\\\\') || '.next', + }; + + const clientValues = { + ...isomorphicValues, + // Get the path part of `assetPrefix`, minus any trailing slash. (We use a placeholder for the origin if + // `assetPreix` doesn't include one. Since we only care about the path, it doesn't matter what it is.) + __rewriteFramesAssetPrefixPath__: assetPrefix + ? new URL(assetPrefix, 'http://dogs.are.great').pathname.replace(/\/$/, '') + : '', + }; + newConfig.module.rules.push( { test: /sentry\.server\.config\.(jsx?|tsx?)/, @@ -718,16 +720,5 @@ function addValueInjectionLoader( }, ], }, - { - test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, - use: [ - { - loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'), - options: { - values: isomorphicValues, - }, - }, - ], - }, ); } From 4e8f3aab7331d36fbe4a68ead4615f9f0f78ac14 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 12 Dec 2022 07:35:57 +0000 Subject: [PATCH 3/6] Improve comment wording --- packages/nextjs/src/config/loaders/valueInjectionLoader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/loaders/valueInjectionLoader.ts b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts index fbdae367cdaa..3a434fda1a43 100644 --- a/packages/nextjs/src/config/loaders/valueInjectionLoader.ts +++ b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts @@ -8,7 +8,7 @@ type LoaderOptions = { * Set values on the global/window object at the start of a module. * * Options: - * - `values`: A record where the keys correspond to the keys of the global values to set and the values + * - `values`: An object where the keys correspond to the keys of the global values to set and the values * correspond to the values of the values on the global object. Values must be JSON serializable. */ export default function valueInjectionLoader(this: LoaderThis, userCode: string): string { From be36164fffa683d7393f546b9bd5922a9c798fe5 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 12 Dec 2022 07:36:13 +0000 Subject: [PATCH 4/6] Use quotes around key --- packages/nextjs/src/config/loaders/valueInjectionLoader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/loaders/valueInjectionLoader.ts b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts index 3a434fda1a43..be8340dccdf3 100644 --- a/packages/nextjs/src/config/loaders/valueInjectionLoader.ts +++ b/packages/nextjs/src/config/loaders/valueInjectionLoader.ts @@ -19,7 +19,7 @@ export default function valueInjectionLoader(this: LoaderThis, us let injectedCode = 'var _sentryCollisionFreeGlobalObject = typeof window === "undefined" ? global : window;\n'; Object.entries(values).forEach(([key, value]) => { - injectedCode += `_sentryCollisionFreeGlobalObject.${key} = ${JSON.stringify(value)};\n`; + injectedCode += `_sentryCollisionFreeGlobalObject["${key}"] = ${JSON.stringify(value)};\n`; }); return `${injectedCode}\n${userCode}`; From 9b548da75755e7273b09b2d8bba4475c13341ab7 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 12 Dec 2022 10:22:45 +0000 Subject: [PATCH 5/6] Remove redundant test --- packages/nextjs/test/config/loaders.test.ts | 24 --------------------- 1 file changed, 24 deletions(-) diff --git a/packages/nextjs/test/config/loaders.test.ts b/packages/nextjs/test/config/loaders.test.ts index 4053f1d90457..0584473d1e7d 100644 --- a/packages/nextjs/test/config/loaders.test.ts +++ b/packages/nextjs/test/config/loaders.test.ts @@ -78,30 +78,6 @@ describe('webpack loaders', () => { ], }); }); - - it('adds `valueInjection` loader with release values to client and server configs', async () => { - const finalWebpackConfig = await materializeFinalWebpackConfig({ - exportedNextConfig, - incomingWebpackConfig: clientWebpackConfig, - incomingWebpackBuildContext: clientBuildContext, - userSentryWebpackPluginConfig: userSentryWebpackPluginConfig, - }); - - expect(finalWebpackConfig.module.rules).toContainEqual({ - test: /sentry\.(server|client)\.config\.(jsx?|tsx?)/, - use: [ - { - loader: expect.stringEndingWith('valueInjectionLoader.js'), - options: { - values: { - SENTRY_RELEASE: { id: 'doGsaREgReaT' }, - SENTRY_RELEASES: { 'simulator@squirrelChasers': { id: 'doGsaREgReaT' } }, - }, - }, - }, - ], - }); - }); }); }); From a75807cecffde4bde59d100ed45afcb30443f1a1 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 12 Dec 2022 10:23:04 +0000 Subject: [PATCH 6/6] Add comment explaining objectContaining({}) --- packages/nextjs/test/config/loaders.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/test/config/loaders.test.ts b/packages/nextjs/test/config/loaders.test.ts index 0584473d1e7d..714d3388782c 100644 --- a/packages/nextjs/test/config/loaders.test.ts +++ b/packages/nextjs/test/config/loaders.test.ts @@ -7,7 +7,6 @@ import { exportedNextConfig, serverBuildContext, serverWebpackConfig, - userSentryWebpackPluginConfig, } from './fixtures'; import { materializeFinalWebpackConfig } from './testUtils'; @@ -53,6 +52,9 @@ describe('webpack loaders', () => { use: [ { loader: expect.stringEndingWith('valueInjectionLoader.js'), + // We use `expect.objectContaining({})` rather than `expect.any(Object)` to match any plain object because + // the latter will also match arrays, regexes, dates, sets, etc. - anything whose `typeof` value is + // `'object'`. options: expect.objectContaining({ values: expect.objectContaining({}) }), }, ], @@ -73,6 +75,9 @@ describe('webpack loaders', () => { use: [ { loader: expect.stringEndingWith('valueInjectionLoader.js'), + // We use `expect.objectContaining({})` rather than `expect.any(Object)` to match any plain object because + // the latter will also match arrays, regexes, dates, sets, etc. - anything whose `typeof` value is + // `'object'`. options: expect.objectContaining({ values: expect.objectContaining({}) }), }, ],