Skip to content

Conversation

@timfish
Copy link
Collaborator

@timfish timfish commented Nov 2, 2025

This PR:

  • Splits the browser build output into separate development and production builds
  • References these two builds in the package.json exports
  • Adds a Rollup plugin to production builds which can strip out code wrapped with development-only magic comments
  • Adds the spotlight integration to the default integrations in development mode only
  • Also adds this plugin for browser bundles

The development build has this code:

image

But production builds have this stripped out:

image

@github-actions
Copy link
Contributor

github-actions bot commented Nov 2, 2025

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,802 - 8,837 -0%
GET With Sentry 1,378 16% 1,275 +8%
GET With Sentry (error only) 6,135 70% 5,923 +4%
POST Baseline 1,202 - 1,153 +4%
POST With Sentry 553 46% 476 +16%
POST With Sentry (error only) 1,079 90% 1,018 +6%
MYSQL Baseline 3,366 - 3,212 +5%
MYSQL With Sentry 457 14% 366 +25%
MYSQL With Sentry (error only) 2,737 81% 2,570 +6%

View base workflow run

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.

This looks really promising, thanks Tim!

(I realize this is still in draft so feel free to ignore this review if you're still planning on making changes)

@timfish timfish force-pushed the timfish/build/dev-prod-browser-build branch from 8d0f261 to 92bc9f6 Compare November 3, 2025 12:04
@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.64 kB +0.03% +6 B 🔺
@sentry/browser - with treeshaking flags 23.13 kB +0.04% +8 B 🔺
@sentry/browser (incl. Tracing) 41.27 kB +0.01% +4 B 🔺
@sentry/browser (incl. Tracing, Profiling) 45.55 kB +0.02% +8 B 🔺
@sentry/browser (incl. Tracing, Replay) 79.51 kB +0.01% +4 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 69.21 kB +0.02% +7 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 84.21 kB +0.01% +1 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 96.38 kB +0.01% +5 B 🔺
@sentry/browser (incl. Feedback) 41.32 kB +0.02% +7 B 🔺
@sentry/browser (incl. sendFeedback) 29.32 kB +0.03% +7 B 🔺
@sentry/browser (incl. FeedbackAsync) 34.24 kB +0.02% +5 B 🔺
@sentry/react 26.32 kB -0.02% -5 B 🔽
@sentry/react (incl. Tracing) 43.22 kB -0.06% -24 B 🔽
@sentry/vue 29.14 kB +0.03% +6 B 🔺
@sentry/vue (incl. Tracing) 43.05 kB +0.01% +4 B 🔺
@sentry/svelte 24.65 kB +0.03% +5 B 🔺
CDN Bundle 26.91 kB +0.03% +8 B 🔺
CDN Bundle (incl. Tracing) 41.8 kB +0.01% +2 B 🔺
CDN Bundle (incl. Tracing, Replay) 78.07 kB +0.01% +1 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 83.56 kB +0.01% +2 B 🔺
CDN Bundle - uncompressed 78.91 kB +0.02% +14 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 124.02 kB +0.02% +14 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 239.22 kB +0.01% +14 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 251.98 kB +0.01% +14 B 🔺
@sentry/nextjs (client) 45.37 kB +0.02% +6 B 🔺
@sentry/sveltekit (client) 41.67 kB +0.01% +3 B 🔺
@sentry/node-core 50.81 kB -0.01% -1 B 🔽
@sentry/node 157.88 kB +0.01% +1 B 🔺
@sentry/node - without tracing 92.69 kB - -
@sentry/aws-serverless 106.42 kB +0.01% +3 B 🔺

View base workflow run

@timfish timfish force-pushed the timfish/build/dev-prod-browser-build branch from 41be108 to eb515c4 Compare November 3, 2025 13:02
@timfish
Copy link
Collaborator Author

timfish commented Nov 3, 2025

Needs some tests to confirm Spotlight actually works in dev mode...

@timfish timfish marked this pull request as ready for review November 3, 2025 13:28
if (!defaultIntegrations) {
defaultIntegrations = [];
}
defaultIntegrations.push(spotlightBrowserIntegration());
Copy link
Member

Choose a reason for hiding this comment

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

This is not correct as we need to pass options.spotlight as an argument to spotlightBrowserIntegration as {sidecarUrl: options.spotlight} if it's a string.

Suggested change
defaultIntegrations.push(spotlightBrowserIntegration());
defaultIntegrations.push(spotlightBrowserIntegration(typeof options.spotlight === 'string' ? {sidecarUrl: options.spotlight} : undefined));

options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations;

/* rollup-include-development-only */
if (options.spotlight) {
Copy link
Member

Choose a reason for hiding this comment

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

How hard would it be to fill this value from the env variables? I'm okay with trying all variants like PUBLIC_SENTRY_SPOTLIGHT or VITE_SENTRY_SPOTLIGHT etc.

Happy to do this in a follow up too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah probably best in a follow up PR. If we can keep it between the magic comments it'll all get striped out!

if (!pattern.test(code)) return null;
const replaced = code.replace(pattern, '');
return { code: replaced, map: null };
}
Copy link

Choose a reason for hiding this comment

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

Bug: Regex Global State Mutates, Breaks Replacement

The regex pattern has the global flag (g) and is being reused. When pattern.test(code) is called on line 133, it modifies the regex's internal lastIndex property. This causes the subsequent code.replace(pattern, '') call on line 134 to potentially fail or behave incorrectly because the regex state has been mutated. The regex will start matching from the lastIndex position set by the test() call rather than from the beginning. This could result in development-only code blocks not being properly removed from production builds. The fix is to either: 1) use pattern.test() without the global flag, 2) reset pattern.lastIndex = 0 between calls, or 3) use code.includes() or code.match() for the check instead.

Fix in Cursor Fix in Web

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.

4 participants