Skip to content

Commit c8a941c

Browse files
authored
ref(nextjs): Exclude cross-platform tracing code from bundles (#3978)
The `@sentry/tracing` package contains shared code, code which only applies to browser, and code which only applies to node. At the moment, webpack is unable to treeshake the former out of the server build and the latter out of the client build. This PR does that treeshaking manually, taking advantage of webpack 5’s new ability[1] to replace a module with an empty object by setting `resolve.alias.<someModule> = false` in the webpack config. Notes: - All node tracing integrations have been moved into a `node` folder, so we don't need to worry that at some point a non-node integration might get added to `integrations` and be accidentally excluded. - Normally we only care about bundle size on the browser side, but since Vercel turns server routes into serverless functions, bundle size matters on the backend, too, so the change was made in both directions. - As a point of reference, on my test app it took the sentry portion of the client `_app` bundle down from ~32.3 kb to ~30.6 kb, which is a little over a 5% savings. [1] https://webpack.js.org/configuration/resolve/#resolvealias
1 parent 42dffe5 commit c8a941c

File tree

9 files changed

+29
-8
lines changed

9 files changed

+29
-8
lines changed

packages/nextjs/src/config/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export type WebpackConfigObject = {
4242
output: { filename: string; path: string };
4343
target: string;
4444
context: string;
45+
resolve?: {
46+
alias?: { [key: string]: string | boolean };
47+
};
4548
} & {
4649
// other webpack options
4750
[key: string]: unknown;

packages/nextjs/src/config/webpack.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ export function constructWebpackConfigFunction(
6060
const origEntryProperty = newConfig.entry;
6161
newConfig.entry = async () => addSentryToEntryProperty(origEntryProperty, buildContext);
6262

63+
// In webpack 5, you can get webpack to replace any module you'd like with an empty object, just by setting its
64+
// `resolve.alias` value to `false`. Not much of our code is neatly separated into "things node needs" and "things
65+
// the browser needs," but where it is, we can save ~1.6 kb in eventual bundle size by excluding code we know we
66+
// don't need. (Normally this would only matter for the client side, but because vercel turns backend code into
67+
// serverless functions, it's worthwhile to do it for both.)
68+
if (buildContext.webpack.version.startsWith('5')) {
69+
const excludedTracingDir = buildContext.isServer ? 'browser' : 'integrations/node';
70+
newConfig.resolve = {
71+
...newConfig.resolve,
72+
alias: {
73+
...newConfig.resolve?.alias,
74+
[path.resolve(buildContext.dir, `./node_modules/@sentry/tracing/esm/${excludedTracingDir}`)]: false,
75+
// TODO It's not clear if it will ever pull from `dist` (in testing it never does), so we may not need this.
76+
[path.resolve(buildContext.dir, `./node_modules/@sentry/tracing/dist/${excludedTracingDir}`)]: false,
77+
},
78+
};
79+
}
80+
6381
// Enable the Sentry plugin (which uploads source maps to Sentry when not in dev) by default
6482
const enableWebpackPlugin = buildContext.isServer
6583
? !userNextConfig.sentry?.disableServerWebpackPlugin
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { Express } from './express';
2-
export { Postgres } from './postgres';
3-
export { Mysql } from './mysql';
4-
export { Mongo } from './mongo';
1+
export { Express } from './node/express';
2+
export { Postgres } from './node/postgres';
3+
export { Mysql } from './node/mysql';
4+
export { Mongo } from './node/mongo';

packages/tracing/test/integrations/mongo.test.ts renamed to packages/tracing/test/integrations/node/mongo.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable @typescript-eslint/unbound-method */
22
import { Hub, Scope } from '@sentry/hub';
33

4-
import { Mongo } from '../../src/integrations/mongo';
5-
import { Span } from '../../src/span';
4+
import { Mongo } from '../../../src/integrations/node/mongo';
5+
import { Span } from '../../../src/span';
66

77
class Collection {
88
public collectionName: string = 'mockedCollectionName';

packages/tracing/test/integrations/postgres.test.ts renamed to packages/tracing/test/integrations/node/postgres.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable @typescript-eslint/unbound-method */
22
import { Hub, Scope } from '@sentry/hub';
33

4-
import { Postgres } from '../../src/integrations/postgres';
5-
import { Span } from '../../src/span';
4+
import { Postgres } from '../../../src/integrations/node/postgres';
5+
import { Span } from '../../../src/span';
66

77
class PgClient {
88
// https://node-postgres.com/api/client#clientquery

0 commit comments

Comments
 (0)