getsentry / sentry-javascript-bundler-plugins

JavaScript Bundler Plugins for Sentry
https://sentry.io
BSD 3-Clause "New" or "Revised" License
141 stars 36 forks source link

Inject release SHA only to one output JS file #477

Closed Lemonexe closed 9 months ago

Lemonexe commented 9 months ago

Description

sentryVitePlugin currently does not work well with native vite code-splitting using splitVendorChunkPlugin. It works without error, but in a way that defeats the whole purpose of it, unfortunately.

In our SPA, we have used Sentry for some time, and wanted to do the code-splitting instead of bundling everything to index.js. The motivation is the usual – to let clients cache the large vendor.js file, and only invalidate cache for the much smaller index.js, because most deployments do not change dependencies.

Current behavior

With following setup in vite.config.mts:

plugins: [
    react(),
    sentryVitePlugin({ authToken: 'foo', org: 'bar', project: 'asdf' }),
    splitVendorChunkPlugin(),
]

If you vite build, it creates both files with a fingerprint (mock fingerprints for demo): index-111.js vendor-999.js

Now if I commit a change in our app code without affecting dependencies, I'd expect it to only invalidate index: index-222.js vendor-999.js

But unfortunately, it also invalidates vendor: index-222.js vendor-888.js

Which defeats the whole purpose of it.. I've tracked this down to the sentryVitePlugin, which injects the code with release SHA, and it modifies every output file, thus changing its fingerprint.

What I've tried:

Desired behavior

Ideally, add a new option to limit the injection to specific files, maybe something like this:

release: {
    injectOnlyToFiles: ['index']
}

I have searched in issues and did not find this problem mentioned by anyone. After all, it's very easy to miss, because seemingly it works correctly, it just changes the fingerprint when it shouldn't. Maybe https://github.com/getsentry/sentry-javascript-bundler-plugins/issues/418 is kind of related, but I'm not sure about that..?

lforst commented 9 months ago

Hi, you don't have to use the plugin's injection mechanism. You can simply pass in a release value yourself. For the debug ID mechansim of associating source maps, injection into every file is a necessity, we cannot get around that. The injection should be deterministic so the hash should only change when stuff is actually changing.

Lemonexe commented 9 months ago

Hi @lforst , thank you for the explanation. I didn't realize the solution is that simple – explicitly setting the release name in vite.config.mts, and in the app code where we call Sentry.init().

It works wonderfully – vendor.js is not invalidated, errors are assigned to the release name, source maps are uploaded for the release name βœ…

So basically, the code injection is a useful default to save us a few lines of config, by setting the release name during runtime. But we can just as well do it explicitly during build time πŸ‘

Suggestion: there could be a brief mention in docs – that disabling injection and setting release name explicitly is useful in case we want to the code-splitting. Otherwise it truly does mutate the vendor.js, and change its fingerprint, when there were no changes to its content.