Skip to content

Commit f8b74f0

Browse files
authored
feat(tracing): Expose BrowserTracing in non-tracing bundles (#7479)
1 parent 572e4f5 commit f8b74f0

27 files changed

+287
-169
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
"karma-firefox-launcher": "^1.1.0",
9898
"lerna": "6.5.0-alpha.2",
9999
"madge": "4.0.2",
100-
"magic-string": "^0.27.0",
101100
"mocha": "^6.1.4",
102101
"nodemon": "^2.0.16",
103102
"npm-run-all": "^4.1.5",
@@ -108,7 +107,6 @@
108107
"rollup": "^2.67.1",
109108
"rollup-plugin-cleanup": "3.2.1",
110109
"rollup-plugin-license": "^2.6.1",
111-
"rollup-plugin-modify": "^3.0.0",
112110
"rollup-plugin-terser": "^7.0.2",
113111
"rollup-plugin-typescript2": "^0.31.2",
114112
"sinon": "^7.3.2",

packages/browser-integration-tests/suites/replay/replayShim/test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ sentryTest(
3030
await forceFlushReplay();
3131

3232
expect(requestCount).toBe(0);
33-
expect(consoleMessages).toEqual([
34-
'You are using new Replay() even though this bundle does not include the replay integration.',
35-
]);
33+
expect(consoleMessages).toEqual(['You are using new Replay() even though this bundle does not include replay.']);
3634
},
3735
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
sampleRate: 1,
8+
integrations: [new Sentry.Integrations.BrowserTracing()],
9+
});
10+
11+
// This should not fail
12+
Sentry.addTracingExtensions();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button onclick="console.log('Test log')">Click me</button>
8+
</body>
9+
</html>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../utils/fixtures';
4+
5+
sentryTest(
6+
'exports a shim Integrations.BrowserTracing integration for non-tracing bundles',
7+
async ({ getLocalTestPath, page }) => {
8+
const bundle = process.env.PW_BUNDLE;
9+
const tracingOnly = Boolean(process.env.PW_TRACING_ONLY);
10+
11+
if (!bundle || !bundle.startsWith('bundle_') || tracingOnly) {
12+
sentryTest.skip();
13+
}
14+
15+
const consoleMessages: string[] = [];
16+
page.on('console', msg => consoleMessages.push(msg.text()));
17+
18+
let requestCount = 0;
19+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
20+
requestCount++;
21+
return route.fulfill({
22+
status: 200,
23+
contentType: 'application/json',
24+
body: JSON.stringify({ id: 'test-id' }),
25+
});
26+
});
27+
28+
const url = await getLocalTestPath({ testDir: __dirname });
29+
30+
await page.goto(url);
31+
32+
expect(requestCount).toBe(0);
33+
expect(consoleMessages).toEqual([
34+
'You are using new BrowserTracing() even though this bundle does not include tracing.',
35+
]);
36+
},
37+
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
sampleRate: 1,
8+
integrations: [new Sentry.BrowserTracing()],
9+
});
10+
11+
// This should not fail
12+
Sentry.addTracingExtensions();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button onclick="console.log('Test log')">Click me</button>
8+
</body>
9+
</html>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../utils/fixtures';
4+
5+
sentryTest('exports a shim BrowserTracing integration for non-tracing bundles', async ({ getLocalTestPath, page }) => {
6+
const bundle = process.env.PW_BUNDLE;
7+
const tracingOnly = Boolean(process.env.PW_TRACING_ONLY);
8+
9+
if (!bundle || !bundle.startsWith('bundle_') || tracingOnly) {
10+
sentryTest.skip();
11+
}
12+
13+
const consoleMessages: string[] = [];
14+
page.on('console', msg => consoleMessages.push(msg.text()));
15+
16+
let requestCount = 0;
17+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
18+
requestCount++;
19+
return route.fulfill({
20+
status: 200,
21+
contentType: 'application/json',
22+
body: JSON.stringify({ id: 'test-id' }),
23+
});
24+
});
25+
26+
const url = await getLocalTestPath({ testDir: __dirname });
27+
28+
await page.goto(url);
29+
30+
expect(requestCount).toBe(0);
31+
expect(consoleMessages).toEqual([
32+
'You are using new BrowserTracing() even though this bundle does not include tracing.',
33+
]);
34+
});

packages/browser/rollup.bundle.config.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ const builds = [];
55
['es5', 'es6'].forEach(jsVersion => {
66
const baseBundleConfig = makeBaseBundleConfig({
77
bundleType: 'standalone',
8-
entrypoints: ['src/index.ts'],
8+
entrypoints: ['src/index.bundle.ts'],
99
jsVersion,
1010
licenseTitle: '@sentry/browser',
11-
includeReplay: 'shim',
1211
outputFileBase: () => `bundles/bundle${jsVersion === 'es5' ? '.es5' : ''}`,
1312
});
1413

@@ -18,11 +17,10 @@ const builds = [];
1817
// Full bundle incl. replay only available for es6
1918
const replayBaseBundleConfig = makeBaseBundleConfig({
2019
bundleType: 'standalone',
21-
entrypoints: ['src/index.ts'],
20+
entrypoints: ['src/index.bundle.replay.ts'],
2221
jsVersion: 'es6',
2322
licenseTitle: '@sentry/browser & @sentry/replay',
2423
outputFileBase: () => 'bundles/bundle.replay',
25-
includeReplay: true,
2624
});
2725

2826
builds.push(...makeBundleConfigVariants(replayBaseBundleConfig));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export * from './exports';
2+
3+
import { Integrations as CoreIntegrations } from '@sentry/core';
4+
import type { Integration } from '@sentry/types';
5+
6+
import { WINDOW } from './helpers';
7+
import * as BrowserIntegrations from './integrations';
8+
9+
let windowIntegrations = {};
10+
11+
// This block is needed to add compatibility with the integrations packages when used with a CDN
12+
if (WINDOW.Sentry && WINDOW.Sentry.Integrations) {
13+
windowIntegrations = WINDOW.Sentry.Integrations;
14+
}
15+
16+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17+
const INTEGRATIONS: Record<string, new (...args: any[]) => Integration> = {
18+
...windowIntegrations,
19+
...CoreIntegrations,
20+
...BrowserIntegrations,
21+
};
22+
23+
export { INTEGRATIONS as Integrations };
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// This is exported so the loader does not fail when switching off Replay/Tracing
2+
import { addTracingExtensions, BrowserTracing } from '@sentry-internal/integration-shims';
3+
import { Replay } from '@sentry/replay';
4+
5+
import * as Sentry from './index.bundle.base';
6+
7+
// TODO (v8): Remove this as it was only needed for backwards compatibility
8+
Sentry.Integrations.Replay = Replay;
9+
10+
Sentry.Integrations.BrowserTracing = BrowserTracing;
11+
12+
export * from './index.bundle.base';
13+
export { BrowserTracing, addTracingExtensions, Replay };

packages/browser/src/index.bundle.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This is exported so the loader does not fail when switching off Replay/Tracing
2+
import { addTracingExtensions, BrowserTracing, Replay } from '@sentry-internal/integration-shims';
3+
4+
import * as Sentry from './index.bundle.base';
5+
6+
// TODO (v8): Remove this as it was only needed for backwards compatibility
7+
Sentry.Integrations.Replay = Replay;
8+
9+
Sentry.Integrations.BrowserTracing = BrowserTracing;
10+
11+
export * from './index.bundle.base';
12+
export { BrowserTracing, addTracingExtensions, Replay };

packages/browser/src/index.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,9 @@ const INTEGRATIONS = {
2020

2121
export { INTEGRATIONS as Integrations };
2222

23-
// DO NOT DELETE THESE COMMENTS!
24-
// We want to exclude Replay/Offline from CDN bundles, so we remove the block below with our
25-
// makeExcludeBlockPlugin Rollup plugin when generating bundles. Everything between
26-
// ROLLUP_EXCLUDE_*_FROM_BUNDLES_BEGIN and _END__ is removed for bundles.
27-
28-
// __ROLLUP_EXCLUDE_REPLAY_FROM_BUNDLES_BEGIN__
2923
export { Replay } from '@sentry/replay';
30-
// __ROLLUP_EXCLUDE_REPLAY_FROM_BUNDLES_END__
31-
32-
// __ROLLUP_EXCLUDE_BROWSER_TRACING_FROM_BUNDLES_BEGIN__
3324
export { BrowserTracing } from '@sentry-internal/tracing';
3425
export { addTracingExtensions } from '@sentry/core';
35-
// __ROLLUP_EXCLUDE_BROWSER_TRACING_FROM_BUNDLES_END__
36-
37-
// __ROLLUP_EXCLUDE_OFFLINE_FROM_BUNDLES_BEGIN__
3826
export { makeBrowserOfflineTransport } from './transports/offline';
39-
// __ROLLUP_EXCLUDE_OFFLINE_FROM_BUNDLES_END__
40-
41-
// __ROLLUP_EXCLUDE_BROWSER_PROFILING_FROM_BUNDLES_BEGIN__
4227
export { onProfilingStartRouteTransaction } from './profiling/hubextensions';
4328
export { BrowserProfilingIntegration } from './profiling/integration';
44-
// __ROLLUP_EXCLUDE_BROWSER_PROFILING_FROM_BUNDLES_END__
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { BrowserTracing as BrowserTracingShim } from '@sentry-internal/integration-shims';
2+
import { Replay } from '@sentry/browser';
3+
4+
import * as TracingReplayBundle from '../../src/index.bundle.replay';
5+
6+
describe('index.bundle.replay', () => {
7+
it('has correct exports', () => {
8+
Object.keys(TracingReplayBundle.Integrations).forEach(key => {
9+
// Skip BrowserTracing because it doesn't have a static id field.
10+
if (key === 'BrowserTracing') {
11+
return;
12+
}
13+
14+
expect((TracingReplayBundle.Integrations[key] as any).id).toStrictEqual(expect.any(String));
15+
});
16+
17+
expect(TracingReplayBundle.Integrations.Replay).toBe(Replay);
18+
expect(TracingReplayBundle.Replay).toBe(Replay);
19+
20+
expect(TracingReplayBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim);
21+
expect(TracingReplayBundle.BrowserTracing).toBe(BrowserTracingShim);
22+
});
23+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { BrowserTracing as BrowserTracingShim, Replay as ReplayShim } from '@sentry-internal/integration-shims';
2+
3+
import * as TracingBundle from '../../src/index.bundle';
4+
5+
describe('index.bundle', () => {
6+
it('has correct exports', () => {
7+
Object.keys(TracingBundle.Integrations).forEach(key => {
8+
// Skip BrowserTracing because it doesn't have a static id field.
9+
if (key === 'BrowserTracing') {
10+
return;
11+
}
12+
13+
expect((TracingBundle.Integrations[key] as any).id).toStrictEqual(expect.any(String));
14+
});
15+
16+
expect(TracingBundle.Integrations.Replay).toBe(ReplayShim);
17+
expect(TracingBundle.Replay).toBe(ReplayShim);
18+
19+
expect(TracingBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim);
20+
expect(TracingBundle.BrowserTracing).toBe(BrowserTracingShim);
21+
});
22+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { Integration } from '@sentry/types';
2+
3+
/**
4+
* This is a shim for the BrowserTracing integration.
5+
* It is needed in order for the CDN bundles to continue working when users add/remove tracing
6+
* from it, without changing their config. This is necessary for the loader mechanism.
7+
*/
8+
class BrowserTracingShim implements Integration {
9+
/**
10+
* @inheritDoc
11+
*/
12+
public static id: string = 'BrowserTracing';
13+
14+
/**
15+
* @inheritDoc
16+
*/
17+
public name: string = BrowserTracingShim.id;
18+
19+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20+
public constructor(_options: any) {
21+
// eslint-disable-next-line no-console
22+
console.error('You are using new BrowserTracing() even though this bundle does not include tracing.');
23+
}
24+
25+
/** jsdoc */
26+
public setupOnce(): void {
27+
// noop
28+
}
29+
}
30+
31+
export { BrowserTracingShim as BrowserTracing };
32+
33+
/** Shim function */
34+
export function addTracingExtensions(): void {
35+
// noop
36+
}

packages/integration-shims/src/Replay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ReplayShim implements Integration {
1919
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2020
public constructor(_options: any) {
2121
// eslint-disable-next-line no-console
22-
console.error('You are using new Replay() even though this bundle does not include the replay integration.');
22+
console.error('You are using new Replay() even though this bundle does not include replay.');
2323
}
2424

2525
/** jsdoc */
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export * from './Replay';
1+
export { Replay } from './Replay';
2+
export { BrowserTracing, addTracingExtensions } from './BrowserTracing';

packages/tracing/rollup.bundle.config.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const builds = [];
88
entrypoints: ['src/index.bundle.ts'],
99
jsVersion,
1010
licenseTitle: '@sentry/tracing & @sentry/browser',
11-
includeReplay: false,
1211
outputFileBase: () => `bundles/bundle.tracing${jsVersion === 'es5' ? '.es5' : ''}`,
1312
});
1413

@@ -22,7 +21,6 @@ const replayBaseBundleConfig = makeBaseBundleConfig({
2221
jsVersion: 'es6',
2322
licenseTitle: '@sentry/tracing & @sentry/browser & @sentry/replay',
2423
outputFileBase: () => 'bundles/bundle.tracing.replay',
25-
includeReplay: true,
2624
});
2725

2826
builds.push(...makeBundleConfigVariants(replayBaseBundleConfig));

packages/tracing/src/index.bundle.base.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,8 @@ if (GLOBAL_OBJ.Sentry && GLOBAL_OBJ.Sentry.Integrations) {
6767
windowIntegrations = GLOBAL_OBJ.Sentry.Integrations;
6868
}
6969

70-
// For whatever reason, it does not recognize BrowserTracing or some of the BrowserIntegrations as Integration
71-
const INTEGRATIONS: Record<
72-
string,
73-
Integration | typeof BrowserTracing | typeof BrowserIntegrations[keyof typeof BrowserIntegrations]
74-
> = {
70+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
71+
const INTEGRATIONS: Record<string, new (...args: any[]) => Integration> = {
7572
...windowIntegrations,
7673
...BrowserIntegrations,
7774
BrowserTracing,
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { Replay } from '@sentry/browser';
22

3-
import * as Sentry from './index.bundle';
3+
import * as Sentry from './index.bundle.base';
44

55
// TODO (v8): Remove this as it was only needed for backwards compatibility
66
// We want replay to be available under Sentry.Replay, to be consistent
77
// with the NPM package version.
88
Sentry.Integrations.Replay = Replay;
99

1010
export { Replay };
11-
1211
export * from './index.bundle.base';

0 commit comments

Comments
 (0)