Skip to content

Commit

Permalink
feat(tracing): Expose BrowserTracing in non-tracing bundles (#7479)
Browse files Browse the repository at this point in the history
  • Loading branch information
mydea authored Mar 20, 2023
1 parent 572e4f5 commit f8b74f0
Show file tree
Hide file tree
Showing 27 changed files with 287 additions and 169 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
"karma-firefox-launcher": "^1.1.0",
"lerna": "6.5.0-alpha.2",
"madge": "4.0.2",
"magic-string": "^0.27.0",
"mocha": "^6.1.4",
"nodemon": "^2.0.16",
"npm-run-all": "^4.1.5",
Expand All @@ -108,7 +107,6 @@
"rollup": "^2.67.1",
"rollup-plugin-cleanup": "3.2.1",
"rollup-plugin-license": "^2.6.1",
"rollup-plugin-modify": "^3.0.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.31.2",
"sinon": "^7.3.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ sentryTest(
await forceFlushReplay();

expect(requestCount).toBe(0);
expect(consoleMessages).toEqual([
'You are using new Replay() even though this bundle does not include the replay integration.',
]);
expect(consoleMessages).toEqual(['You are using new Replay() even though this bundle does not include replay.']);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
sampleRate: 1,
integrations: [new Sentry.Integrations.BrowserTracing()],
});

// This should not fail
Sentry.addTracingExtensions();
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button onclick="console.log('Test log')">Click me</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';

sentryTest(
'exports a shim Integrations.BrowserTracing integration for non-tracing bundles',
async ({ getLocalTestPath, page }) => {
const bundle = process.env.PW_BUNDLE;
const tracingOnly = Boolean(process.env.PW_TRACING_ONLY);

if (!bundle || !bundle.startsWith('bundle_') || tracingOnly) {
sentryTest.skip();
}

const consoleMessages: string[] = [];
page.on('console', msg => consoleMessages.push(msg.text()));

let requestCount = 0;
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
requestCount++;
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);

expect(requestCount).toBe(0);
expect(consoleMessages).toEqual([
'You are using new BrowserTracing() even though this bundle does not include tracing.',
]);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
sampleRate: 1,
integrations: [new Sentry.BrowserTracing()],
});

// This should not fail
Sentry.addTracingExtensions();
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button onclick="console.log('Test log')">Click me</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';

sentryTest('exports a shim BrowserTracing integration for non-tracing bundles', async ({ getLocalTestPath, page }) => {
const bundle = process.env.PW_BUNDLE;
const tracingOnly = Boolean(process.env.PW_TRACING_ONLY);

if (!bundle || !bundle.startsWith('bundle_') || tracingOnly) {
sentryTest.skip();
}

const consoleMessages: string[] = [];
page.on('console', msg => consoleMessages.push(msg.text()));

let requestCount = 0;
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
requestCount++;
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);

expect(requestCount).toBe(0);
expect(consoleMessages).toEqual([
'You are using new BrowserTracing() even though this bundle does not include tracing.',
]);
});
6 changes: 2 additions & 4 deletions packages/browser/rollup.bundle.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ const builds = [];
['es5', 'es6'].forEach(jsVersion => {
const baseBundleConfig = makeBaseBundleConfig({
bundleType: 'standalone',
entrypoints: ['src/index.ts'],
entrypoints: ['src/index.bundle.ts'],
jsVersion,
licenseTitle: '@sentry/browser',
includeReplay: 'shim',
outputFileBase: () => `bundles/bundle${jsVersion === 'es5' ? '.es5' : ''}`,
});

Expand All @@ -18,11 +17,10 @@ const builds = [];
// Full bundle incl. replay only available for es6
const replayBaseBundleConfig = makeBaseBundleConfig({
bundleType: 'standalone',
entrypoints: ['src/index.ts'],
entrypoints: ['src/index.bundle.replay.ts'],
jsVersion: 'es6',
licenseTitle: '@sentry/browser & @sentry/replay',
outputFileBase: () => 'bundles/bundle.replay',
includeReplay: true,
});

builds.push(...makeBundleConfigVariants(replayBaseBundleConfig));
Expand Down
23 changes: 23 additions & 0 deletions packages/browser/src/index.bundle.base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export * from './exports';

import { Integrations as CoreIntegrations } from '@sentry/core';
import type { Integration } from '@sentry/types';

import { WINDOW } from './helpers';
import * as BrowserIntegrations from './integrations';

let windowIntegrations = {};

// This block is needed to add compatibility with the integrations packages when used with a CDN
if (WINDOW.Sentry && WINDOW.Sentry.Integrations) {
windowIntegrations = WINDOW.Sentry.Integrations;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const INTEGRATIONS: Record<string, new (...args: any[]) => Integration> = {
...windowIntegrations,
...CoreIntegrations,
...BrowserIntegrations,
};

export { INTEGRATIONS as Integrations };
13 changes: 13 additions & 0 deletions packages/browser/src/index.bundle.replay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This is exported so the loader does not fail when switching off Replay/Tracing
import { addTracingExtensions, BrowserTracing } from '@sentry-internal/integration-shims';
import { Replay } from '@sentry/replay';

import * as Sentry from './index.bundle.base';

// TODO (v8): Remove this as it was only needed for backwards compatibility
Sentry.Integrations.Replay = Replay;

Sentry.Integrations.BrowserTracing = BrowserTracing;

export * from './index.bundle.base';
export { BrowserTracing, addTracingExtensions, Replay };
12 changes: 12 additions & 0 deletions packages/browser/src/index.bundle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// This is exported so the loader does not fail when switching off Replay/Tracing
import { addTracingExtensions, BrowserTracing, Replay } from '@sentry-internal/integration-shims';

import * as Sentry from './index.bundle.base';

// TODO (v8): Remove this as it was only needed for backwards compatibility
Sentry.Integrations.Replay = Replay;

Sentry.Integrations.BrowserTracing = BrowserTracing;

export * from './index.bundle.base';
export { BrowserTracing, addTracingExtensions, Replay };
16 changes: 0 additions & 16 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,9 @@ const INTEGRATIONS = {

export { INTEGRATIONS as Integrations };

// DO NOT DELETE THESE COMMENTS!
// We want to exclude Replay/Offline from CDN bundles, so we remove the block below with our
// makeExcludeBlockPlugin Rollup plugin when generating bundles. Everything between
// ROLLUP_EXCLUDE_*_FROM_BUNDLES_BEGIN and _END__ is removed for bundles.

// __ROLLUP_EXCLUDE_REPLAY_FROM_BUNDLES_BEGIN__
export { Replay } from '@sentry/replay';
// __ROLLUP_EXCLUDE_REPLAY_FROM_BUNDLES_END__

// __ROLLUP_EXCLUDE_BROWSER_TRACING_FROM_BUNDLES_BEGIN__
export { BrowserTracing } from '@sentry-internal/tracing';
export { addTracingExtensions } from '@sentry/core';
// __ROLLUP_EXCLUDE_BROWSER_TRACING_FROM_BUNDLES_END__

// __ROLLUP_EXCLUDE_OFFLINE_FROM_BUNDLES_BEGIN__
export { makeBrowserOfflineTransport } from './transports/offline';
// __ROLLUP_EXCLUDE_OFFLINE_FROM_BUNDLES_END__

// __ROLLUP_EXCLUDE_BROWSER_PROFILING_FROM_BUNDLES_BEGIN__
export { onProfilingStartRouteTransaction } from './profiling/hubextensions';
export { BrowserProfilingIntegration } from './profiling/integration';
// __ROLLUP_EXCLUDE_BROWSER_PROFILING_FROM_BUNDLES_END__
23 changes: 23 additions & 0 deletions packages/browser/test/unit/index.bundle.replay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { BrowserTracing as BrowserTracingShim } from '@sentry-internal/integration-shims';
import { Replay } from '@sentry/browser';

import * as TracingReplayBundle from '../../src/index.bundle.replay';

describe('index.bundle.replay', () => {
it('has correct exports', () => {
Object.keys(TracingReplayBundle.Integrations).forEach(key => {
// Skip BrowserTracing because it doesn't have a static id field.
if (key === 'BrowserTracing') {
return;
}

expect((TracingReplayBundle.Integrations[key] as any).id).toStrictEqual(expect.any(String));
});

expect(TracingReplayBundle.Integrations.Replay).toBe(Replay);
expect(TracingReplayBundle.Replay).toBe(Replay);

expect(TracingReplayBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim);
expect(TracingReplayBundle.BrowserTracing).toBe(BrowserTracingShim);
});
});
22 changes: 22 additions & 0 deletions packages/browser/test/unit/index.bundle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BrowserTracing as BrowserTracingShim, Replay as ReplayShim } from '@sentry-internal/integration-shims';

import * as TracingBundle from '../../src/index.bundle';

describe('index.bundle', () => {
it('has correct exports', () => {
Object.keys(TracingBundle.Integrations).forEach(key => {
// Skip BrowserTracing because it doesn't have a static id field.
if (key === 'BrowserTracing') {
return;
}

expect((TracingBundle.Integrations[key] as any).id).toStrictEqual(expect.any(String));
});

expect(TracingBundle.Integrations.Replay).toBe(ReplayShim);
expect(TracingBundle.Replay).toBe(ReplayShim);

expect(TracingBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim);
expect(TracingBundle.BrowserTracing).toBe(BrowserTracingShim);
});
});
36 changes: 36 additions & 0 deletions packages/integration-shims/src/BrowserTracing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Integration } from '@sentry/types';

/**
* This is a shim for the BrowserTracing integration.
* It is needed in order for the CDN bundles to continue working when users add/remove tracing
* from it, without changing their config. This is necessary for the loader mechanism.
*/
class BrowserTracingShim implements Integration {
/**
* @inheritDoc
*/
public static id: string = 'BrowserTracing';

/**
* @inheritDoc
*/
public name: string = BrowserTracingShim.id;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(_options: any) {
// eslint-disable-next-line no-console
console.error('You are using new BrowserTracing() even though this bundle does not include tracing.');
}

/** jsdoc */
public setupOnce(): void {
// noop
}
}

export { BrowserTracingShim as BrowserTracing };

/** Shim function */
export function addTracingExtensions(): void {
// noop
}
2 changes: 1 addition & 1 deletion packages/integration-shims/src/Replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ReplayShim implements Integration {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(_options: any) {
// eslint-disable-next-line no-console
console.error('You are using new Replay() even though this bundle does not include the replay integration.');
console.error('You are using new Replay() even though this bundle does not include replay.');
}

/** jsdoc */
Expand Down
3 changes: 2 additions & 1 deletion packages/integration-shims/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './Replay';
export { Replay } from './Replay';
export { BrowserTracing, addTracingExtensions } from './BrowserTracing';
2 changes: 0 additions & 2 deletions packages/tracing/rollup.bundle.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const builds = [];
entrypoints: ['src/index.bundle.ts'],
jsVersion,
licenseTitle: '@sentry/tracing & @sentry/browser',
includeReplay: false,
outputFileBase: () => `bundles/bundle.tracing${jsVersion === 'es5' ? '.es5' : ''}`,
});

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

builds.push(...makeBundleConfigVariants(replayBaseBundleConfig));
Expand Down
7 changes: 2 additions & 5 deletions packages/tracing/src/index.bundle.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,8 @@ if (GLOBAL_OBJ.Sentry && GLOBAL_OBJ.Sentry.Integrations) {
windowIntegrations = GLOBAL_OBJ.Sentry.Integrations;
}

// For whatever reason, it does not recognize BrowserTracing or some of the BrowserIntegrations as Integration
const INTEGRATIONS: Record<
string,
Integration | typeof BrowserTracing | typeof BrowserIntegrations[keyof typeof BrowserIntegrations]
> = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const INTEGRATIONS: Record<string, new (...args: any[]) => Integration> = {
...windowIntegrations,
...BrowserIntegrations,
BrowserTracing,
Expand Down
3 changes: 1 addition & 2 deletions packages/tracing/src/index.bundle.replay.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Replay } from '@sentry/browser';

import * as Sentry from './index.bundle';
import * as Sentry from './index.bundle.base';

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

export { Replay };

export * from './index.bundle.base';
Loading

0 comments on commit f8b74f0

Please sign in to comment.