Skip to content

Commit 41f9db7

Browse files
committed
feat(browser): Export Replay integration from Browser SDK
wip
1 parent 60b5a7b commit 41f9db7

File tree

12 files changed

+84
-25
lines changed

12 files changed

+84
-25
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"karma-firefox-launcher": "^1.1.0",
8888
"lerna": "3.13.4",
8989
"madge": "4.0.2",
90+
"magic-string": "^0.27.0",
9091
"mocha": "^6.1.4",
9192
"nodemon": "^2.0.16",
9293
"npm-run-all": "^4.1.5",

packages/browser/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
},
1818
"dependencies": {
1919
"@sentry/core": "7.25.0",
20+
"@sentry/replay": "7.25.0",
2021
"@sentry/types": "7.25.0",
2122
"@sentry/utils": "7.25.0",
2223
"tslib": "^1.9.3"

packages/browser/src/client.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, Scope, SDK_VERSION } from '@sentry/core';
2-
import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel } from '@sentry/types';
2+
import {
3+
BrowserClientReplayOptions,
4+
ClientOptions,
5+
Event,
6+
EventHint,
7+
Options,
8+
Severity,
9+
SeverityLevel,
10+
} from '@sentry/types';
311
import { createClientReportEnvelope, dsnToString, logger, serializeEnvelope } from '@sentry/utils';
412

513
import { eventFromException, eventFromMessage } from './eventbuilder';
614
import { WINDOW } from './helpers';
715
import { Breadcrumbs } from './integrations';
816
import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs';
917
import { BrowserTransportOptions } from './transports/types';
10-
11-
type BrowserClientReplayOptions = {
12-
/**
13-
* The sample rate for session-long replays.
14-
* 1.0 will record all sessions and 0 will record none.
15-
*/
16-
replaysSessionSampleRate?: number;
17-
18-
/**
19-
* The sample rate for sessions that has had an error occur.
20-
* This is independent of `sessionSampleRate`.
21-
* 1.0 will record all sessions and 0 will record none.
22-
*/
23-
replaysOnErrorSampleRate?: number;
24-
};
25-
2618
/**
2719
* Configuration options for the Sentry Browser SDK.
2820
* @see @sentry/types Options for more information.

packages/browser/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,12 @@ const INTEGRATIONS = {
1919
};
2020

2121
export { INTEGRATIONS as Integrations };
22+
23+
// DO NOT DELETE THESE COMMENTS!
24+
// We want to exclude Replay from CDN bundles, so we remove the block below with our
25+
// excludeReplay Rollup plugin when generating bundles. Everything between
26+
// ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN and _END__ is removed for bundles.
27+
28+
// __ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__
29+
export { Replay } from '@sentry/replay';
30+
// __ROLLUP_EXCLUDE_FROM_BUNDLES_END__

packages/replay/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
"homepage": "https://github.com/getsentry/sentry-replay#readme",
4747
"devDependencies": {
4848
"@babel/core": "^7.17.5",
49-
"@sentry/browser": "7.25.0",
5049
"@types/lodash.debounce": "4.0.7",
5150
"@types/pako": "^2.0.0",
5251
"jsdom-worker": "^0.2.1",

packages/replay/src/integration.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import type { BrowserClient, BrowserOptions } from '@sentry/browser';
21
import { getCurrentHub } from '@sentry/core';
3-
import { Integration } from '@sentry/types';
2+
import { BrowserClientReplayOptions, Integration } from '@sentry/types';
43

54
import { DEFAULT_ERROR_SAMPLE_RATE, DEFAULT_SESSION_SAMPLE_RATE } from './constants';
65
import { ReplayContainer } from './replay';
@@ -184,8 +183,8 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
184183

185184
/** Parse Replay-related options from SDK options */
186185
private _loadReplayOptionsFromClient(): void {
187-
const client = getCurrentHub().getClient() as BrowserClient | undefined;
188-
const opt = client && (client.getOptions() as BrowserOptions | undefined);
186+
const client = getCurrentHub().getClient();
187+
const opt = client && (client.getOptions() as BrowserClientReplayOptions | undefined);
189188

190189
if (opt && typeof opt.replaysSessionSampleRate === 'number') {
191190
this.options.sessionSampleRate = opt.replaysSessionSampleRate;

packages/types/src/browseroptions.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Options added to the Browser SDK's init options that are specific for Replay.
3+
* Note: This type was moved to @sentry/types to avoid a circular dependency between Browser and Replay.
4+
*/
5+
export type BrowserClientReplayOptions = {
6+
/**
7+
* The sample rate for session-long replays.
8+
* 1.0 will record all sessions and 0 will record none.
9+
*/
10+
replaysSessionSampleRate?: number;
11+
12+
/**
13+
* The sample rate for sessions that has had an error occur.
14+
* This is independent of `sessionSampleRate`.
15+
* 1.0 will record all sessions and 0 will record none.
16+
*/
17+
replaysOnErrorSampleRate?: number;
18+
};

packages/types/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,5 @@ export type {
9393
export type { User, UserFeedback } from './user';
9494
export type { WrappedFunction } from './wrappedfunction';
9595
export type { Instrumenter } from './instrumenter';
96+
97+
export type { BrowserClientReplayOptions } from './browseroptions';

rollup/bundleHelpers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
makeSucrasePlugin,
1717
makeTerserPlugin,
1818
makeTSPlugin,
19+
makeExcludeReplayPlugin,
1920
} from './plugins/index.js';
2021
import { mergePlugins } from './utils';
2122

@@ -30,6 +31,7 @@ export function makeBaseBundleConfig(options) {
3031
const markAsBrowserBuildPlugin = makeBrowserBuildPlugin(true);
3132
const licensePlugin = makeLicensePlugin(licenseTitle);
3233
const tsPlugin = makeTSPlugin(jsVersion.toLowerCase());
34+
const excludeReplayPlugin = makeExcludeReplayPlugin();
3335

3436
// The `commonjs` plugin is the `esModuleInterop` of the bundling world. When used with `transformMixedEsModules`, it
3537
// will include all dependencies, imported or required, in the final bundle. (Without it, CJS modules aren't included
@@ -43,7 +45,7 @@ export function makeBaseBundleConfig(options) {
4345
name: 'Sentry',
4446
},
4547
context: 'window',
46-
plugins: [markAsBrowserBuildPlugin],
48+
plugins: [markAsBrowserBuildPlugin, excludeReplayPlugin],
4749
};
4850

4951
// used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle)

rollup/plugins/bundlePlugins.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import resolve from '@rollup/plugin-node-resolve';
1515
import replace from '@rollup/plugin-replace';
1616
import { terser } from 'rollup-plugin-terser';
1717
import typescript from 'rollup-plugin-typescript2';
18+
import MagicString from 'magic-string';
1819

1920
/**
2021
* Create a plugin to add an identification banner to the top of stand-alone bundles.
@@ -165,6 +166,34 @@ export function makeTSPlugin(jsVersion) {
165166
return plugin;
166167
}
167168

169+
/**
170+
* Creates a Rollup plugin that removes all code between the `__ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__`
171+
* and `__ROLLUP_EXCLUDE_FROM_BUNDLES_END__` comment guards. This is used to exclude the Replay integration
172+
* from the browser and browser+tracing bundles.
173+
*/
174+
export function makeExcludeReplayPlugin() {
175+
const replacementRegex = /\/\/ __ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__(.|\n)*__ROLLUP_EXCLUDE_FROM_BUNDLES_END__/gm;
176+
177+
const plugin = {
178+
transform(code) {
179+
if (!replacementRegex.test(code)) {
180+
return null;
181+
}
182+
183+
const ms = new MagicString(code);
184+
const transformedCode = ms.replace(new RegExp(replacementRegex), '');
185+
return {
186+
code: transformedCode.toString(),
187+
map: transformedCode.generateMap({ hires: true }),
188+
};
189+
},
190+
};
191+
192+
plugin.name = 'excludeReplay';
193+
194+
return plugin;
195+
}
196+
168197
// We don't pass these plugins any options which need to be calculated or changed by us, so no need to wrap them in
169198
// another factory function, as they are themselves already factory functions.
170199
export { resolve as makeNodeResolvePlugin };

rollup/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function mergePlugins(pluginsA, pluginsB) {
1919
// Hacky way to make sure the ones we care about end up where they belong in the order. (Really the TS and sucrase
2020
// plugins are tied - both should come first - but they're mutually exclusive, so they can come in arbitrary order
2121
// here.)
22-
const order = ['typescript', 'sucrase', '...', 'terser', 'license'];
22+
const order = ['excludeReplay', 'typescript', 'sucrase', '...', 'terser', 'license'];
2323
const sortKeyA = order.includes(a.name) ? a.name : '...';
2424
const sortKeyB = order.includes(b.name) ? b.name : '...';
2525

yarn.lock

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2232,7 +2232,7 @@
22322232
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
22332233
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
22342234

2235-
"@jridgewell/[email protected]", "@jridgewell/sourcemap-codec@^1.4.10":
2235+
"@jridgewell/[email protected]", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13":
22362236
version "1.4.14"
22372237
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
22382238
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
@@ -16567,6 +16567,13 @@ magic-string@^0.26.2:
1656716567
dependencies:
1656816568
sourcemap-codec "^1.4.8"
1656916569

16570+
magic-string@^0.27.0:
16571+
version "0.27.0"
16572+
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
16573+
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
16574+
dependencies:
16575+
"@jridgewell/sourcemap-codec" "^1.4.13"
16576+
1657016577
make-dir@^1.0.0:
1657116578
version "1.3.0"
1657216579
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"

0 commit comments

Comments
 (0)