Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(browser): Export Replay integration from Browser SDK #6508

Merged
merged 7 commits into from
Dec 15, 2022

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Dec 13, 2022

This PR exports the Replay integration from @sentry/replay in @sentry/browser. This will eliminate the need for users to separately install the @sentry/replay package as they have to do right now. Instead, they can just use Replay like it's part of the core Browser SDK or any FE Framework SDK that builds on top of Browser:

import * as Sentry from '@sentry/browser'; // or @sentry/react, ...

Sentry.init({
  // dsn, other options, etc
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  integrations: [new Sentry.Replay()]
});

Alternatively, import { Replay } from '@sentry/browser' works, too.

Note: This does not affect users who imported the integration from @sentry/replay so it should be fully backwards compatible.

Bundle Size Concerns

As far as I tested, for the NPM package, everything Replay-related is tree-shaken out by bundlers if Replay is not used.

For standalone CDN bundles of browser and browser+tracing, we have to first remove the export from index.ts in the Browser package, before we transpile and bundle so that the integration isn't included in them. In the future, we can think about a complete bundle that contains Replay but this is out of scope for this PR and its issue.

To remove the export from index.ts, this PR introduces a new rollup plugin that removes all code between specific comment guards. I chose this approach over creating a separate index.bundle.ts file because we'd anyhow need to apply some rollup intervention to select the correct index file for the browser+tracing bundles. Since we're already experienced by now with rollup plugins, I figured, it'd be a nicer way.

ref: #6326

@Lms24 Lms24 force-pushed the lms-replay-export-from-browser branch 2 times, most recently from 044e434 to 41f9db7 Compare December 13, 2022 10:12
@Lms24 Lms24 marked this pull request as ready for review December 13, 2022 10:35
@github-actions
Copy link
Contributor

github-actions bot commented Dec 13, 2022

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.78 KB (-0.01% 🔽)
@sentry/browser - ES5 CDN Bundle (minified) 61.27 KB (0%)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.57 KB (+0.01% 🔺)
@sentry/browser - ES6 CDN Bundle (minified) 54.8 KB (0%)
@sentry/browser - Webpack (gzipped + minified) 20.34 KB (0%)
@sentry/browser - Webpack (minified) 66.48 KB (0%)
@sentry/react - Webpack (gzipped + minified) 20.36 KB (0%)
@sentry/nextjs Client - Webpack (gzipped + minified) 47.57 KB (0%)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 26.76 KB (+0.02% 🔺)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 25.19 KB (-0.01% 🔽)
@sentry/replay ES6 CDN Bundle (gzipped + minified) 41.87 KB (0%)
@sentry/replay - Webpack (gzipped + minified) 38.1 KB (0%)

@Lms24 Lms24 force-pushed the lms-replay-export-from-browser branch from 53a28ea to 2591d2a Compare December 14, 2022 10:33
@Lms24 Lms24 force-pushed the lms-replay-export-from-browser branch from 2591d2a to 92661a6 Compare December 14, 2022 10:34
Copy link
Member

@lforst lforst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this. Very pragmatic for what it achieves IMO. Almost ready to approve this. I would just like to resolve all conversations before pressing the button.

rollup/plugins/bundlePlugins.js Show resolved Hide resolved
*/
export function makeExcludeReplayPlugin() {
const replacementRegex = /\/\/ __ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__(.|\n)*__ROLLUP_EXCLUDE_FROM_BUNDLES_END__/m;
const browserIndexFilePath = path.resolve(__dirname, '../../packages/browser/src/index.ts');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m: Just a tiny bit worried that if we move this file (or less likely but worse, the place of the guard) that this is gonna break. Thinking can we somehow test for these cases? Or make this more robust.

Honestly, I can't come up with anything obvious that wouldn't be super complicated so I am totally fine with just leaving it as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO the best way to check this is via size checks. What about actually decreasing the allowed size limits to reasonable amounts? E.g. currently we have stuff like 100kb in there for browser. What if we just set this to like "current size + 10kb"? Then tests would actually fail when something becomes too large?

Copy link
Member Author

@Lms24 Lms24 Dec 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea with size-check! I can lower the limits as this should be a good indicator when something goes wrong with the replay export removal.

In terms of this being brittle, yes I agree but then again, we're talking about the main index.ts file which IMO is unlikely to change location or name. Obviously, moving the guard would still be a problem but size-check would let us know about this (fwiw, even without limit adjustments as it failed while I still had a bug in this PR).

If we decide to make this plugin more general at some point, we could pass a "transform files allowlist" or something similar to make changing file entries more easy but for now I'd vote to keep the plugin as is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to pull this out into its own PR so we have a better history as to why we made this change: #6543

rollup/utils.js Show resolved Hide resolved
import { createClientReportEnvelope, dsnToString, logger, serializeEnvelope } from '@sentry/utils';

import { eventFromException, eventFromMessage } from './eventbuilder';
import { WINDOW } from './helpers';
import { Breadcrumbs } from './integrations';
import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs';
import { BrowserTransportOptions } from './transports/types';

type BrowserClientReplayOptions = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering: Why are we moving this type into the types package?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that @sentry/replay does not need to import anything from @sentry/browser, to avoid circular dependencies.

import { getCurrentHub } from '@sentry/core';
import { Integration } from '@sentry/types';
import { BrowserClientReplayOptions, Integration } from '@sentry/types';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l/m: Could we keep this as import type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lms24 added a commit that referenced this pull request Dec 15, 2022
Lower our `size-limit` maximum bundle size limits. Previously, most of them were set to rather arbitrary high numbers (100Kb mostly). With these adjustments, we lower them to +10Kb of each entry's current size. The reason for doing this is to catch problems with tree shaking or unexpected large bundle size hits more reliably. As outlined in #6508 (comment), we could for instance catch the Replay integration being wrongfully included in to our standalone Browser SDK CDN bundles. 

In case the limits are hit, the "Size Limit" CI job will fail.
Copy link
Member

@mydea mydea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work!

@Lms24 Lms24 merged commit 2c09d9a into master Dec 15, 2022
@Lms24 Lms24 deleted the lms-replay-export-from-browser branch December 15, 2022 12:19
Lms24 added a commit that referenced this pull request Dec 16, 2022
…n tests (#6570)

This patch fixes the broken NextJS and Remix integration tests which were unable to look up the local version of `@sentry/replay` before. Replay is now a dependency of these tests because they depend on `@sentry/browser` (which in turn depends on Replay after #6508).
Lms24 added a commit to getsentry/sentry-docs that referenced this pull request Dec 20, 2022
This PR updates the Session Replay docs after we released version 7.27.0 of the JS SDKs. With this new version, users don't need to explicitly install `@sentry/replay` anymore, as it is now a dependency of `@sentry/browser` which [exports the Replay integration](getsentry/sentry-javascript#6508). 

* Update the session replay setup page
* Update the session replay onboarding wizard

ref #getsentry/sentry-javascript#6326

Note: I'd like to keep this PR open for a few days (Monday or so) just to make sure 7.27.0 isn't breaking anything
@billyvg
Copy link
Member

billyvg commented Dec 20, 2022

@Lms24 So now to test a local replays package, do we link @sentry/browser?

@martinklepsch
Copy link

Just as a data point: We use Sentry from ClojureScript, which comes with its own compiler and way of integrating npm packages into the bundle. Unfortunately the replay code is not omitted and this change added 130kb to our build.

While this is definitely a minority of the Sentry userbase I'd advocate for a more conservative approach to these types of decisions. This change saved a lot of people 1 line of code but adds 130kb to the bundle for people using less common (not anticipated) setups.

@lforst
Copy link
Member

lforst commented Mar 1, 2023

@martinklepsch I am gonna make the call here and say that if users care about build/bundle size, they should use tooling that does tree shaking and dead code elimination. The size of the npm module is not something we care about - CDN bundles are a different story since there is nothing users can do to reduce their size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants