Skip to content

Commit

Permalink
feat(replay): Allow to treeshake rrweb features (#9274)
Browse files Browse the repository at this point in the history
This depends on getsentry/rrweb#114 to be merged
first, but allows to configure build time flags to shake out certain
rrweb features that may not be used.

It also adds a size limit entry that shows the total bundle size with
everything that can be shaken out removed, incl. debug stuff. Bundle
size is about ~11kb gzipped less in this scenario, which is not bad.
  • Loading branch information
mydea committed Oct 19, 2023
1 parent dc68c09 commit aea3905
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 28 deletions.
19 changes: 19 additions & 0 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ module.exports = [
gzip: true,
limit: '90 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay) - Webpack with treeshaking flags (gzipped)',
path: 'packages/browser/build/npm/esm/index.js',
import: '{ init, Replay, BrowserTracing }',
gzip: true,
limit: '90 KB',
modifyWebpackConfig: function (config) {
const webpack = require('webpack');
config.plugins.push(
new webpack.DefinePlugin({
__SENTRY_DEBUG__: false,
__RRWEB_EXCLUDE_CANVAS__: true,
__RRWEB_EXCLUDE_SHADOW_DOM__: true,
__RRWEB_EXCLUDE_IFRAME__: true,
}),
);
return config;
},
},
{
name: '@sentry/browser (incl. Tracing) - Webpack (gzipped)',
path: 'packages/browser/build/npm/esm/index.js',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"@rollup/plugin-sucrase": "^4.0.3",
"@rollup/plugin-typescript": "^8.3.1",
"@size-limit/preset-small-lib": "~9.0.0",
"@size-limit/webpack": "~9.0.0",
"@strictsoftware/typedoc-plugin-monorepo": "^0.3.1",
"@types/chai": "^4.1.3",
"@types/jest": "^27.4.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/replay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"devDependencies": {
"@babel/core": "^7.17.5",
"@sentry-internal/replay-worker": "7.74.1",
"@sentry-internal/rrweb": "2.0.1",
"@sentry-internal/rrweb-snapshot": "2.0.1",
"@sentry-internal/rrweb": "2.1.0",
"@sentry-internal/rrweb-snapshot": "2.1.0",
"jsdom-worker": "^0.2.1"
},
"dependencies": {
Expand Down
10 changes: 8 additions & 2 deletions rollup/bundleHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
makeBrowserBuildPlugin,
makeCommonJSPlugin,
makeIsDebugBuildPlugin,
makeRrwebBuildPlugin,
makeLicensePlugin,
makeNodeResolvePlugin,
makeCleanupPlugin,
Expand All @@ -34,6 +35,11 @@ export function makeBaseBundleConfig(options) {
const markAsBrowserBuildPlugin = makeBrowserBuildPlugin(true);
const licensePlugin = makeLicensePlugin(licenseTitle);
const tsPlugin = makeTSPlugin('es5');
const rrwebBuildPlugin = makeRrwebBuildPlugin({
excludeCanvas: true,
excludeIframe: false,
excludeShadowDom: false,
});

// 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 @@ -51,7 +57,7 @@ export function makeBaseBundleConfig(options) {
},
},
context: 'window',
plugins: [markAsBrowserBuildPlugin],
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin],
};

// used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle)
Expand Down Expand Up @@ -84,7 +90,7 @@ export function makeBaseBundleConfig(options) {
// code to add after the CJS wrapper
footer: '}(window));',
},
plugins: [markAsBrowserBuildPlugin],
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin],
};

// used by `@sentry/serverless`, when creating the lambda layer
Expand Down
15 changes: 14 additions & 1 deletion rollup/npmHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
makeNodeResolvePlugin,
makeCleanupPlugin,
makeSucrasePlugin,
makeRrwebBuildPlugin,
makeDebugBuildStatementReplacePlugin,
makeSetSDKSourcePlugin,
} from './plugins/index.js';
Expand All @@ -34,6 +35,11 @@ export function makeBaseNPMConfig(options = {}) {
const cleanupPlugin = makeCleanupPlugin();
const extractPolyfillsPlugin = makeExtractPolyfillsPlugin();
const setSdkSourcePlugin = makeSetSDKSourcePlugin('npm');
const rrwebBuildPlugin = makeRrwebBuildPlugin({
excludeCanvas: undefined,
excludeShadowDom: undefined,
excludeIframe: undefined,
});

const defaultBaseConfig = {
input: entrypoints,
Expand Down Expand Up @@ -84,7 +90,14 @@ export function makeBaseNPMConfig(options = {}) {
interop: esModuleInterop ? 'auto' : 'esModule',
},

plugins: [nodeResolvePlugin, setSdkSourcePlugin, sucrasePlugin, debugBuildStatementReplacePlugin, cleanupPlugin],
plugins: [
nodeResolvePlugin,
setSdkSourcePlugin,
sucrasePlugin,
debugBuildStatementReplacePlugin,
rrwebBuildPlugin,
cleanupPlugin,
],

// don't include imported modules from outside the package in the final output
external: [
Expand Down
29 changes: 29 additions & 0 deletions rollup/plugins/npmPlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,33 @@ export function makeDebugBuildStatementReplacePlugin() {
});
}

/**
* Creates a plugin to replace build flags of rrweb with either a constant (if passed true/false) or with a safe statement that:
* a) evaluates to `true`
* b) can easily be modified by our users' bundlers to evaluate to false, facilitating the treeshaking of logger code.
*
* When `undefined` is passed,
* end users can define e.g. `__SENTRY_EXCLUDE_CANVAS__` in their bundler to shake out canvas specific rrweb code.
*/
export function makeRrwebBuildPlugin({ excludeCanvas, excludeShadowDom, excludeIframe } = {}) {
const values = {};

if (typeof excludeCanvas === 'boolean') {
values['__RRWEB_EXCLUDE_CANVAS__'] = excludeCanvas;
}

if (typeof excludeShadowDom === 'boolean') {
values['__RRWEB_EXCLUDE_SHADOW_DOM__'] = excludeShadowDom;
}

if (typeof excludeIframe === 'boolean') {
values['__RRWEB_EXCLUDE_IFRAME__'] = excludeIframe;
}

return replace({
preventAssignment: true,
values,
});
}

export { makeExtractPolyfillsPlugin } from './extractPolyfillsPlugin.js';

0 comments on commit aea3905

Please sign in to comment.