diff --git a/.size-limit.js b/.size-limit.js index aee03e5a242c..461de7995ad1 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -78,4 +78,10 @@ module.exports = [ limit: '48 KB', ignore: ['@sentry/browser', '@sentry/utils', '@sentry/core', '@sentry/types'], }, + { + name: '@sentry/browser + @sentry/tracing + @sentry/replay - ES6 CDN Bundle (gzipped + minified)', + path: 'packages/tracing/build/bundles/bundle.tracing.replay.min.js', + gzip: true, + limit: '80 KB', + }, ]; diff --git a/packages/replay/README.md b/packages/replay/README.md index e3dccaa73ac0..187288a315ff 100644 --- a/packages/replay/README.md +++ b/packages/replay/README.md @@ -99,19 +99,11 @@ replay.start(); ## Loading Replay as a CDN Bundle As an alternative to the NPM package, you can load the Replay integration bundle from our CDN. -Note that the Replay bundle **only contains the Replay integration** and not the entire Sentry SDK. -You have to add it in addition to the Sentry Browser SDK bundle: ```js // Browser SDK bundle - -// Replay integration bundle - @@ -132,6 +124,19 @@ Sentry.init({ The Replay initilialization [configuration](#configuration) options are identical to the options of the NPM package. +Alternatively, you can also load the Replay integration separately from other bundles: + +```html + + +``` + Please visit our [CDN bundle docs](https://docs.sentry.io/platforms/javascript/install/cdn/#available-bundles) to get the correct `integrity` checksums for your version. Note that the two bundle versions always have to match. diff --git a/packages/tracing/rollup.bundle.config.js b/packages/tracing/rollup.bundle.config.js index 0d5f4fcc8867..a5f7141b9b74 100644 --- a/packages/tracing/rollup.bundle.config.js +++ b/packages/tracing/rollup.bundle.config.js @@ -1,5 +1,9 @@ +import replace from '@rollup/plugin-replace'; + import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; +import pkg from './package.json'; + const builds = []; ['es5', 'es6'].forEach(jsVersion => { @@ -14,4 +18,26 @@ const builds = []; builds.push(...makeBundleConfigVariants(baseBundleConfig)); }); +// Full bundle incl. replay only avaialable for es6 +const replayBaseBundleConfig = makeBaseBundleConfig({ + bundleType: 'standalone', + entrypoints: ['src/index.bundle.replay.ts'], + jsVersion: 'es6', + licenseTitle: '@sentry/tracing & @sentry/browser & @sentry/replay', + outputFileBase: () => 'bundles/bundle.tracing.replay', + includeReplay: true, + packageSpecificConfig: { + plugins: [ + replace({ + preventAssignment: true, + values: { + __SENTRY_REPLAY_VERSION__: JSON.stringify(pkg.version), + }, + }), + ], + }, +}); + +builds.push(...makeBundleConfigVariants(replayBaseBundleConfig)); + export default builds; diff --git a/packages/tracing/src/index.bundle.replay.ts b/packages/tracing/src/index.bundle.replay.ts new file mode 100644 index 000000000000..b70b443ef682 --- /dev/null +++ b/packages/tracing/src/index.bundle.replay.ts @@ -0,0 +1,7 @@ +import { Replay } from '@sentry/browser'; + +import * as Sentry from './index.bundle'; + +Sentry.Integrations.Replay = Replay; + +export default Sentry; diff --git a/packages/tracing/src/index.bundle.ts b/packages/tracing/src/index.bundle.ts index 13d2bb38c2e2..635be146d639 100644 --- a/packages/tracing/src/index.bundle.ts +++ b/packages/tracing/src/index.bundle.ts @@ -53,6 +53,7 @@ export { export { SDK_VERSION } from '@sentry/browser'; import { Integrations as BrowserIntegrations } from '@sentry/browser'; +import type { Integration } from '@sentry/types'; import { GLOBAL_OBJ } from '@sentry/utils'; import { BrowserTracing } from './browser'; @@ -67,7 +68,11 @@ if (GLOBAL_OBJ.Sentry && GLOBAL_OBJ.Sentry.Integrations) { windowIntegrations = GLOBAL_OBJ.Sentry.Integrations; } -const 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] +> = { ...windowIntegrations, ...BrowserIntegrations, BrowserTracing, diff --git a/packages/tracing/test/index.bundle.replay.test.ts b/packages/tracing/test/index.bundle.replay.test.ts new file mode 100644 index 000000000000..7a55d4c6741e --- /dev/null +++ b/packages/tracing/test/index.bundle.replay.test.ts @@ -0,0 +1,19 @@ +import Sentry from '../src/index.bundle.replay'; + +// Because of the way how we re-export stuff for the replay bundle, we only have a single default export +const { Integrations } = Sentry; + +describe('Integrations export', () => { + it('is exported correctly', () => { + Object.keys(Integrations).forEach(key => { + // Skip BrowserTracing because it doesn't have a static id field. + if (key === 'BrowserTracing') { + return; + } + + expect((Integrations[key] as any).id).toStrictEqual(expect.any(String)); + }); + + expect(Integrations.Replay).toBeDefined(); + }); +}); diff --git a/packages/tracing/test/index.bundle.test.ts b/packages/tracing/test/index.bundle.test.ts index 91f643128d21..494c94a28bfb 100644 --- a/packages/tracing/test/index.bundle.test.ts +++ b/packages/tracing/test/index.bundle.test.ts @@ -8,9 +8,9 @@ describe('Integrations export', () => { return; } - expect(Integrations[key as keyof Omit].id).toStrictEqual( - expect.any(String), - ); + expect((Integrations[key] as any).id).toStrictEqual(expect.any(String)); }); }); + + expect(Integrations.Replay).toBeUndefined(); }); diff --git a/packages/tracing/tsconfig.types.json b/packages/tracing/tsconfig.types.json index 1df465fa6534..0abe8142d426 100644 --- a/packages/tracing/tsconfig.types.json +++ b/packages/tracing/tsconfig.types.json @@ -5,7 +5,7 @@ // the fact that it introduces a dependency on `@sentry/browser` which doesn't exist anywhere else in the SDK, which // then prevents us from building that and this at the same time when doing a parallellized build from the repo root // level. - "exclude": ["src/index.bundle.ts"], + "exclude": ["src/index.bundle.ts", "src/index.bundle.replay.ts"], "compilerOptions": { "declaration": true, diff --git a/rollup/bundleHelpers.js b/rollup/bundleHelpers.js index e5870d7aaba8..5e1772b99ea1 100644 --- a/rollup/bundleHelpers.js +++ b/rollup/bundleHelpers.js @@ -23,7 +23,8 @@ import { mergePlugins } from './utils'; const BUNDLE_VARIANTS = ['.js', '.min.js', '.debug.min.js']; export function makeBaseBundleConfig(options) { - const { bundleType, entrypoints, jsVersion, licenseTitle, outputFileBase, packageSpecificConfig } = options; + const { bundleType, entrypoints, jsVersion, licenseTitle, outputFileBase, packageSpecificConfig, includeReplay } = + options; const nodeResolvePlugin = makeNodeResolvePlugin(); const sucrasePlugin = makeSucrasePlugin(); @@ -45,9 +46,13 @@ export function makeBaseBundleConfig(options) { name: 'Sentry', }, context: 'window', - plugins: [markAsBrowserBuildPlugin, excludeReplayPlugin], + plugins: [markAsBrowserBuildPlugin], }; + if (!includeReplay) { + standAloneBundleConfig.plugins.push(excludeReplayPlugin); + } + // used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle) const addOnBundleConfig = { // These output settings are designed to mimic an IIFE. We don't use Rollup's `iife` format because we don't want to