Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(nextjs): Fix conflict with other libraries modifying webpack entry property #3703

Merged
merged 1 commit into from
Jun 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions packages/nextjs/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ export type WebpackEntryProperty = EntryPropertyObject | EntryPropertyFunction;
// Each value in that object is either a string representing a single entry point, an array of such strings, or an
// object containing either of those, along with other configuration options. In that third case, the entry point(s) are
// listed under the key `import`.
export type EntryPropertyObject =
| { [key: string]: string }
| { [key: string]: Array<string> }
| { [key: string]: EntryPointObject }; // only in webpack 5
export type EntryPropertyObject = {
[key: string]:
| string
| Array<string>
// only in webpack 5
| EntryPointObject;
};

export type EntryPropertyFunction = () => Promise<EntryPropertyObject>;

Expand Down
18 changes: 18 additions & 0 deletions packages/nextjs/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as SentryWebpackPlugin from '@sentry/webpack-plugin';

import {
BuildContext,
EntryPointObject,
EntryPropertyObject,
ExportedNextConfig,
SentryWebpackPluginOptions,
Expand Down Expand Up @@ -151,6 +152,23 @@ async function addSentryToEntryProperty(
// On the client, it's sufficient to inject it into the `main` JS code, which is included in every browser page.
else {
addFileToExistingEntryPoint(newEntryProperty, 'main', SENTRY_CLIENT_CONFIG_FILE);

// To work around a bug in nextjs, we need to ensure that the `main.js` entry is empty (otherwise it'll choose that
// over `main` and we'll lose the change we just made). In case some other library has put something into it, copy
// its contents over before emptying it out. See
// https://github.com/getsentry/sentry-javascript/pull/3696#issuecomment-863363803.)
const mainjsValue = newEntryProperty['main.js'];
if (Array.isArray(mainjsValue) && mainjsValue.length > 0) {
const mainValue = newEntryProperty.main;

// copy the `main.js` entries over
newEntryProperty.main = Array.isArray(mainValue)
? [...mainjsValue, ...mainValue]
: { ...(mainValue as EntryPointObject), import: [...mainjsValue, ...(mainValue as EntryPointObject).import] };

// nuke the entries
newEntryProperty['main.js'] = [];
}
}

return newEntryProperty;
Expand Down
22 changes: 21 additions & 1 deletion packages/nextjs/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,27 @@ describe('webpack config', () => {
});

expect(finalWebpackConfig.entry).toEqual(
expect.objectContaining({ main: expect.arrayContaining(['./sentry.client.config.js']) }),
expect.objectContaining({ main: ['./src/index.ts', './sentry.client.config.js'] }),
);
});

// see https://github.com/getsentry/sentry-javascript/pull/3696#issuecomment-863363803
it('handles non-empty `main.js` entry point', async () => {
const finalWebpackConfig = await materializeFinalWebpackConfig({
userNextConfig,
userSentryWebpackPluginConfig,
incomingWebpackConfig: {
...clientWebpackConfig,
entry: () => Promise.resolve({ main: './src/index.ts', 'main.js': ['sitLieDownRollOver.config.js'] }),
},
incomingWebpackBuildContext: { ...buildContext, isServer: false },
});

expect(finalWebpackConfig.entry).toEqual(
expect.objectContaining({
main: ['sitLieDownRollOver.config.js', './src/index.ts', './sentry.client.config.js'],
'main.js': [],
}),
);
});
});
Expand Down