Skip to content

Commit

Permalink
feat(bundles): Ensure CDN bundles always have a Replay export
Browse files Browse the repository at this point in the history
  • Loading branch information
mydea committed Mar 13, 2023
1 parent 161b8f0 commit 69e9d19
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"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
1 change: 1 addition & 0 deletions packages/browser/rollup.bundle.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const builds = [];
entrypoints: ['src/index.ts'],
jsVersion,
licenseTitle: '@sentry/browser',
includeReplay: 'shim',
outputFileBase: () => `bundles/bundle${jsVersion === 'es5' ? '.es5' : ''}`,
});

Expand Down
46 changes: 46 additions & 0 deletions packages/browser/src/shims/Replay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Integration } from '@sentry/types';

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

/**
* @inheritDoc
*/
public name: string = ReplayShim.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 Replay() even though this bundle does not include the replay integration.');
}

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

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

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

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

export { ReplayShim as Replay };
22 changes: 22 additions & 0 deletions packages/integration-tests/suites/replay/replayShim/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

// Replay should not actually work, but still not error out
window.Replay = new Sentry.Replay({
flushMinDelay: 200,
flushMaxDelay: 200,
});

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
sampleRate: 1,
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 0.0,
integrations: [window.Replay],
});

// Ensure none of these break
window.Replay.start();
window.Replay.stop();
window.Replay.flush();
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>
37 changes: 37 additions & 0 deletions packages/integration-tests/suites/replay/replayShim/test.ts
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 Replay integration for non-replay bundles',
async ({ getLocalTestPath, page, forceFlushReplay }) => {
const bundle = process.env.PW_BUNDLE;

if (!bundle || !bundle.startsWith('bundle_') || bundle.includes('replay')) {
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);
await forceFlushReplay();

expect(requestCount).toBe(0);
expect(consoleMessages).toEqual([
'You are using new Replay() even though this bundle does not include the replay integration.',
]);
},
);
1 change: 1 addition & 0 deletions packages/tracing/rollup.bundle.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const builds = [];
entrypoints: ['src/index.bundle.ts'],
jsVersion,
licenseTitle: '@sentry/tracing & @sentry/browser',
includeReplay: 'shim',
outputFileBase: () => `bundles/bundle.tracing${jsVersion === 'es5' ? '.es5' : ''}`,
});

Expand Down
2 changes: 2 additions & 0 deletions packages/tracing/src/index.bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export {
makeFetchTransport,
makeXHRTransport,
withScope,
// This is replaced with a shim in rollup
Replay,
} from '@sentry/browser';

export { BrowserClient } from '@sentry/browser';
Expand Down
6 changes: 5 additions & 1 deletion rollup/bundleHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
makeTSPlugin,
makeExcludeBlockPlugin,
makeSetSDKSourcePlugin,
makeShimReplayPlugin,
} from './plugins/index.js';
import { mergePlugins } from './utils';

Expand Down Expand Up @@ -45,6 +46,7 @@ export function makeBaseBundleConfig(options) {
const excludeReplayPlugin = makeExcludeBlockPlugin('REPLAY');
const excludeOfflineTransport = makeExcludeBlockPlugin('OFFLINE');
const excludeBrowserProfiling = makeExcludeBlockPlugin('BROWSER_PROFILING');
const replayShimPlugin = makeShimReplayPlugin();

// The `commonjs` plugin is the `esModuleInterop` of the bundling world. When used with `transformMixedEsModules`, it
// will include all dependencies, imported or required, in the final bundle. (Without it, CJS modules aren't included
Expand All @@ -61,7 +63,9 @@ export function makeBaseBundleConfig(options) {
plugins: [markAsBrowserBuildPlugin],
};

if (!includeReplay) {
if (includeReplay === 'shim') {
standAloneBundleConfig.plugins.push(replayShimPlugin);
} else if (!includeReplay) {
standAloneBundleConfig.plugins.push(excludeReplayPlugin);
}

Expand Down
14 changes: 14 additions & 0 deletions rollup/plugins/bundlePlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import replace from '@rollup/plugin-replace';
import { terser } from 'rollup-plugin-terser';
import typescript from 'rollup-plugin-typescript2';
import MagicString from 'magic-string';
import modify from 'rollup-plugin-modify';

/**
* Create a plugin to add an identification banner to the top of stand-alone bundles.
Expand Down Expand Up @@ -215,6 +216,19 @@ export function makeExcludeBlockPlugin(type) {
return plugin;
}

export function makeShimReplayPlugin() {
// This is designed to replace the re-export in browser/index.ts to export the shim
const plugin = modify({
find: '@sentry/replay',
replace: './shims/Replay',
});

// give it a nicer name for later, when we'll need to sort the plugins
plugin.name = 'replayShim';

return plugin;
}

// We don't pass these plugins any options which need to be calculated or changed by us, so no need to wrap them in
// another factory function, as they are themselves already factory functions.
export { resolve as makeNodeResolvePlugin };
Expand Down
22 changes: 22 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17646,6 +17646,13 @@ madge@4.0.2:
typescript "^3.9.5"
walkdir "^0.4.1"

magic-string@0.25.2:
version "0.25.2"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.2.tgz#139c3a729515ec55e96e69e82a11fe890a293ad9"
integrity sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==
dependencies:
sourcemap-codec "^1.4.4"

magic-string@0.25.7:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
Expand Down Expand Up @@ -19826,6 +19833,13 @@ osenv@^0.1.3, osenv@^0.1.5:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"

ospec@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ospec/-/ospec-3.1.0.tgz#d36b8e10110f58f63a463df2390a7a73fe9579a8"
integrity sha512-+nGtjV3vlADp+UGfL51miAh/hB4awPBkQrArhcgG4trAaoA2gKt5bf9w0m9ch9zOr555cHWaCHZEDiBOkNZSxw==
dependencies:
glob "^7.1.3"

p-cancelable@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0"
Expand Down Expand Up @@ -23226,6 +23240,14 @@ rollup-plugin-license@^2.6.1:
spdx-expression-validate "2.0.0"
spdx-satisfies "5.0.1"

rollup-plugin-modify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-modify/-/rollup-plugin-modify-3.0.0.tgz#5326e11dfec247e8bbdd9507f3da1da1e5c7818b"
integrity sha512-p/ffs0Y2jz2dEnWjq1oVC7SY37tuS+aP7whoNaQz1EAAOPg+k3vKJo8cMMWx6xpdd0NzhX4y2YF9o/NPu5YR0Q==
dependencies:
magic-string "0.25.2"
ospec "3.1.0"

rollup-plugin-sourcemaps@^0.6.0, rollup-plugin-sourcemaps@^0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz#bf93913ffe056e414419607f1d02780d7ece84ed"
Expand Down

0 comments on commit 69e9d19

Please sign in to comment.