Skip to content

fix(replay): fix rrweb issue & vendor it #6335

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

Merged
merged 4 commits into from
Dec 6, 2022
Merged

fix(replay): fix rrweb issue & vendor it #6335

merged 4 commits into from
Dec 6, 2022

Conversation

mydea
Copy link
Member

@mydea mydea commented Nov 29, 2022

While debugging the replay issue getsentry/sentry-replay#297, we found that most likely the problem is upstream in rrweb. I created an issue there to fix it: rrweb-io/rrweb#1057

Really, the change is minimal, but the PR is not yet merged & even when it is merged it is not clear when this will be released. Even when it will be released, it will probably go into 2.0.0-alpha.X, which will need some time from us to actually update (as there are no upgrade docs yet etc.)

So, with that in mind, this PR does two things:

  1. Introduce patch-package to fix the exact issue we care about in rrweb
  2. Inline rrweb into the replay bundle

Details

1. Using patch-package to fix rrweb

This approach has two main benefits:
a) We can fix this issue very quickly
b) We still maintain the ability to easily update rrweb in the future

patch-package works at build-time via postinstall, literally fixing the code in your node_modules folder.

2. Inlining rrweb

The only downside of this, really, is that users cannot manually update/pin rrweb to any other version as the one we include. But I think that is acceptable for us. It will be on us to update rrweb whenever they ship fixes/new updates/improvements.

Without this, patch-package could not actually work for users that install @sentry/replay via npm install, as they would not get the patched version. So inlining this is basically a requirement for this to work.

Closes getsentry/sentry-replay#297

@mydea mydea added Dev: Build Package: replay Issues related to the Sentry Replay SDK labels Nov 29, 2022
@mydea mydea self-assigned this Nov 29, 2022
"tslib": "^1.9.3"
},
"dependencies": {
"@sentry/core": "7.22.0",
"@sentry/types": "7.22.0",
"@sentry/utils": "7.22.0",
"lodash.debounce": "^4.0.8",
"rrweb": "^1.1.3"
"lodash.debounce": "^4.0.8"
Copy link
Member Author

Choose a reason for hiding this comment

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

We can probably think about also either inlining this, or actually replace it with some custom code. but we can tackle this later, I'd say!

Copy link
Member

Choose a reason for hiding this comment

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

We have custom (kinda-)debounce logic in IdleTransaction and our Vue SDK (component tracking). So generally I'm +1 for replacing it with custom code. But as you said, that's definitely something to do for later.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 29, 2022

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.6 KB (0%)
@sentry/browser - ES5 CDN Bundle (minified) 60.69 KB (0%)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.37 KB (+0.01% 🔺)
@sentry/browser - ES6 CDN Bundle (minified) 54.26 KB (0%)
@sentry/browser - Webpack (gzipped + minified) 20.13 KB (0%)
@sentry/browser - Webpack (minified) 65.83 KB (0%)
@sentry/react - Webpack (gzipped + minified) 20.16 KB (0%)
@sentry/nextjs Client - Webpack (gzipped + minified) 47.01 KB (0%)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 26.44 KB (+0.01% 🔺)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 24.87 KB (+0.02% 🔺)
@sentry/replay ES6 CDN Bundle (gzipped + minified) 41.72 KB (+0.04% 🔺)
@sentry/replay - Webpack (gzipped + minified) 37.7 KB (+1.31% 🔺)

Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

LGTM. I agree that this is the fastest approach to getting this (and possibly more future) bug(s) fixed.

@@ -89,6 +90,7 @@
"mocha": "^6.1.4",
"nodemon": "^2.0.16",
"npm-run-all": "^4.1.5",
"patch-package": "^6.5.0",
Copy link
Member

Choose a reason for hiding this comment

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

This has to be a top-level dependency because rrweb is hoisted to the root node_modules directory, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, this runs as postinstall when running yarn, so it needs to be on the very top. Also note that the patch itself is also at the root of the project!

@@ -1,6 +1,7 @@
import replace from '@rollup/plugin-replace';
import typescript from '@rollup/plugin-typescript';
import { defineConfig } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
Copy link
Member

@Lms24 Lms24 Nov 30, 2022

Choose a reason for hiding this comment

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

No action required, just putting this here for future reference:

From the @rollup/plugin-node-resolve documentation:

resolveOnly: [...] An Array which instructs the plugin to limit module resolution to those whose names match patterns in the array. Note: Modules not matching any patterns will be marked as external

So iiuc, this is essentially syntactic sugar (EDIT: ok, more than syntactic sugar, as matching has to be performed) around adding everything to the external property in the rollup config except for the modules matching the patterns. I'm fine with using it as long as we can make it work with our rollup configs. In case that doesn't work, we at least know how to work around it.

Copy link
Member Author

Choose a reason for hiding this comment

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

which is weird, as it wasn't marked as external before, right? But still. not included in the bundle 🤔 MAYBE we can drop the config option and only include resolve() (as it is also done in rollup.config.worker.ts), and then it just takes the config from external... I'll give it a try!

Copy link
Member Author

Choose a reason for hiding this comment

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

Update: Yes, that works. So I will remove the resolveOnly config, so it just uses the defined externals!

@mydea mydea force-pushed the fn/replay-fix-rrweb branch from 95e1852 to b9b9281 Compare November 30, 2022 09:21
@mydea
Copy link
Member Author

mydea commented Nov 30, 2022

Note: I tested this in a minimal vue+vite app, and the overall bundle size stayed more or less the same (it actually decreased by ~1kb with this branch).

@mydea mydea force-pushed the fn/replay-fix-rrweb branch 13 times, most recently from 9db6566 to 3e382cb Compare December 5, 2022 14:14
@mydea mydea force-pushed the fn/replay-fix-rrweb branch from 3e382cb to 93f3220 Compare December 6, 2022 09:56
@mydea mydea force-pushed the fn/replay-fix-rrweb branch from 93f3220 to b250c32 Compare December 6, 2022 11:01
@mydea mydea merged commit a171f35 into master Dec 6, 2022
@mydea mydea deleted the fn/replay-fix-rrweb branch December 6, 2022 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dev: Build Package: replay Issues related to the Sentry Replay SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Debug RRWeb styleSheetObserver exception
3 participants