Skip to content

Commit d8feb85

Browse files
authored
fix(v10/nextjs): Only inject applicationKey metadata into browser bundles (#25567)
Backport of: #25565 ## Differences to the original PR - `packages/nextjs/src/config/getBuildPluginOptions.ts`: the server/edge `applicationKey` override is spread after `webpack.unstable_sentryWebpackPluginOptions`, because v10 still spreads those options last and our docs tell webpack users to set `applicationKey` there. Added a test for that path. - `constructTurbopackConfig.ts` and its test: kept v10's `_experimental.turbopackApplicationKey` fallback and its test, which `develop` no longer has.
1 parent 094c3f1 commit d8feb85

4 files changed

Lines changed: 35 additions & 6 deletions

File tree

‎packages/nextjs/src/config/getBuildPluginOptions.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,5 +357,8 @@ export function getBuildPluginOptions({
357357
},
358358
},
359359
...sentryBuildOptions.webpack?.unstable_sentryWebpackPluginOptions,
360+
// Only the browser reads these tags (`thirdPartyErrorFilterIntegration`), so server bundles skip the per-module cost.
361+
// Set after the spread so a key passed through `unstable_sentryWebpackPluginOptions` is dropped on the server too.
362+
...(buildTool === 'webpack-nodejs' || buildTool === 'webpack-edge' ? { applicationKey: undefined } : {}),
360363
};
361364
}

‎packages/nextjs/src/config/turbopack/constructTurbopackConfig.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,14 @@ export function constructTurbopackConfig({
6767
// so it is safe even for node_modules with strict initialization order.
6868
// We only exclude Next.js build polyfills which contain non-standard syntax that causes
6969
// parse errors when any code is prepended (Turbopack re-parses the loader output).
70+
// Server and edge modules are skipped because only the browser reads these tags.
7071
// eslint-disable-next-line typescript/no-deprecated
7172
const applicationKey = userSentryOptions?.applicationKey ?? userSentryOptions?._experimental?.turbopackApplicationKey;
7273
if (applicationKey && nextJsVersion && supportsTurbopackRuleCondition(nextJsVersion)) {
7374
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, {
7475
matcher: '*.{ts,tsx,js,jsx,mjs,cjs}',
7576
rule: {
76-
condition: { not: { path: /next\/dist\/build\/polyfills/ } },
77+
condition: { all: ['browser', { not: { path: /next\/dist\/build\/polyfills/ } }] },
7778
loaders: [
7879
{
7980
loader: path.resolve(__dirname, '..', 'loaders', 'moduleMetadataInjectionLoader.js'),

‎packages/nextjs/test/config/getBuildPluginOptions.test.ts‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,31 @@ describe('getBuildPluginOptions', () => {
9090
expect(result.applicationKey).toBe('my-app-key');
9191
});
9292

93+
it.each(['webpack-nodejs', 'webpack-edge'] as const)('does not forward applicationKey for %s builds', buildTool => {
94+
const result = getBuildPluginOptions({
95+
sentryBuildOptions: { applicationKey: 'my-app-key' },
96+
releaseName: mockReleaseName,
97+
distDirAbsPath: mockDistDirAbsPath,
98+
buildTool,
99+
});
100+
101+
expect(result.applicationKey).toBeUndefined();
102+
});
103+
104+
it.each(['webpack-nodejs', 'webpack-edge'] as const)(
105+
'does not forward applicationKey from unstable_sentryWebpackPluginOptions for %s builds',
106+
buildTool => {
107+
const result = getBuildPluginOptions({
108+
sentryBuildOptions: { webpack: { unstable_sentryWebpackPluginOptions: { applicationKey: 'my-app-key' } } },
109+
releaseName: mockReleaseName,
110+
distDirAbsPath: mockDistDirAbsPath,
111+
buildTool,
112+
});
113+
114+
expect(result.applicationKey).toBeUndefined();
115+
},
116+
);
117+
93118
it('normalizes Windows paths to posix for glob patterns in after-production-compile builds', () => {
94119
const windowsPath = 'C:\\Users\\test\\.next';
95120
const sentryBuildOptions: SentryBuildOptions = {

‎packages/nextjs/test/config/turbopack/constructTurbopackConfig.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ describe('moduleMetadataInjection with applicationKey', () => {
965965
});
966966

967967
expect(result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}']).toEqual({
968-
condition: { not: { path: /next\/dist\/build\/polyfills/ } },
968+
condition: { all: ['browser', { not: { path: /next\/dist\/build\/polyfills/ } }] },
969969
loaders: [
970970
{
971971
loader: '/mocked/path/to/moduleMetadataInjectionLoader.js',
@@ -1010,7 +1010,7 @@ describe('moduleMetadataInjection with applicationKey', () => {
10101010
expect(rule.loaders[0]!.options.applicationKey).toBe('top-level-key');
10111011
});
10121012

1013-
it('should only exclude Next.js polyfills, not all foreign modules', () => {
1013+
it('should only tag browser modules and exclude Next.js polyfills, not all foreign modules', () => {
10141014
const userNextConfig: NextConfigObject = {};
10151015

10161016
const result = constructTurbopackConfig({
@@ -1019,11 +1019,11 @@ describe('moduleMetadataInjection with applicationKey', () => {
10191019
nextJsVersion: '16.0.0',
10201020
});
10211021

1022-
const rule = result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}'] as { condition?: { not: unknown }; loaders: unknown[] };
1022+
const rule = result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}'] as { condition?: unknown; loaders: unknown[] };
10231023
// Unlike component annotation (which uses { not: 'foreign' }), metadata injection
10241024
// must cover node_modules to match the webpack plugin's BannerPlugin behavior.
10251025
// Only Next.js build polyfills are excluded because they have non-standard syntax.
1026-
expect(rule.condition).toEqual({ not: { path: /next\/dist\/build\/polyfills/ } });
1026+
expect(rule.condition).toEqual({ all: ['browser', { not: { path: /next\/dist\/build\/polyfills/ } }] });
10271027
});
10281028

10291029
it('should NOT add metadata loader rule when Next.js < 16', () => {
@@ -1118,7 +1118,7 @@ describe('moduleMetadataInjection with applicationKey', () => {
11181118
});
11191119

11201120
expect(result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}']).toEqual({
1121-
condition: { not: { path: /next\/dist\/build\/polyfills/ } },
1121+
condition: { all: ['browser', { not: { path: /next\/dist\/build\/polyfills/ } }] },
11221122
loaders: [
11231123
{
11241124
loader: '/mocked/path/to/moduleMetadataInjectionLoader.js',

0 commit comments

Comments
 (0)