Skip to content

fix: Use renderChunk for release injection for Rollup/Rolldown/Vite #761

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

Conversation

timfish
Copy link
Collaborator

@timfish timfish commented Jul 16, 2025

To inject release info code via the unplugin hooks we were using resolveId/load/transform but this is not ideal because these hooks get called for every module (ie. every input file!).

We only need to do this injection per bundle output file. We already use Rollups specific renderChunk hook for injecting code which allows us to inject code only into the final chunks.

This PR migrates release injection to use the same renderChunk hook which is already used for metadata injection.

Copy link
Member

@AbhiPrasad AbhiPrasad left a comment

Choose a reason for hiding this comment

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

Do we have an idea of how much this saves build times?

@timfish
Copy link
Collaborator Author

timfish commented Jul 16, 2025

Do we have an idea of how much this saves build times?

Hard to guess really but if this was the only usage of the transform hook this change would reduce the number of plugin hook calls by a couple of orders of magnitude. The ratio is the number of input files vs number of output chunks. For apps with a few dozen dependencies this could be greater than 100 and even larger apps it could be up towards 1000x less hook calls. For bundlers like Rolldown where plugin hook calls are a significant part of its run time, we'll hopefully see the biggest improvements.

However, because we will still be left with other usages of transform, real world results won't be as impressive. We might end up reducing the number of hook calls by only half but it depends on which other bundler plugin features are being used.

For example if bundleSizeOptimizations flags are enabled, this gets called for every input file. I think this is enabled by default for Nextjs and others?

If we can do something like this and use filters to only target specific files we should see a bigger impact.

Rolldown also has it own native define feature that likely has much higher performance than our code because it happens in Rust.

React component annotations require transform but it's not enabled by default 🤷‍♂️

@Lms24
Copy link
Member

Lms24 commented Jul 22, 2025

One thing I realized: #610 (comment)

so if we move to renderChunk, the injection code basically need to be es5(?) compatible? We're talking about this right now in #769 and internally on Slack. According to #770, the required code changes wouldn't be too bad 🤔

@timfish
Copy link
Collaborator Author

timfish commented Jul 22, 2025

I don't really know how polyfilling tools work with bundlers but it's easier to just make the injected code ES5 compatible!

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.

Thanks Tim! Let's merge this after #770 to ensure we don't break anyone accidentally.

As a follow-up, we should also "minify" the release and moduleMetaData injection snippets, given that renderChunk likely happens after minification (At least I think so, since our debugId snippet is already minified). Can you take care of that?

@timfish
Copy link
Collaborator Author

timfish commented Jul 23, 2025

Yeah good point, I'll take care of that.

Out of curiosity I'm going to check the minification plugins to see what hooks they use anyway. Do we enforce/suggest some plugin order when using our bundler plugins?

@AbhiPrasad
Copy link
Member

Do we enforce/suggest some plugin order when using our bundler plugins

I don't think we enforce any ordering, we rely on the individual bundler hooks themselves to run things at the correct time.

@Lms24
Copy link
Member

Lms24 commented Jul 23, 2025

In some rare cases, we need a specific order (e.g. sveltekit). Other than that, some of our plugins using the enforce: 'pre' | 'post' property on individual hooks.

@timfish
Copy link
Collaborator Author

timfish commented Jul 23, 2025

Rollup terser plugin uses renderChunk so I think we do need to minimise our injected code if we don't want to rely on plugin order. If we could ensure minification always came after it would be fine.
https://github.com/rollup/plugins/blob/ad58c8d87c5ab4864e25b5a777290fdf12a3879f/packages/terser/src/module.ts#L19

@timfish
Copy link
Collaborator Author

timfish commented Jul 23, 2025

I minified the release info injected code and also did the same for module metadata injection since the same issues exist there. We could save a small amount of bundle size by combining these plugins.

I moved away from inline snapshots for these tests because with all the code all on a single line it becomes unwieldy!

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.

Thanks for doing the minification right away! I think in this case, it's better to be safe than sorry, and avoid depending on plugin order as much as possible.
Also given that we have integration tests that actually test the behaviour of the (now minified) snippets I think this is safe to merge.

@Lms24 Lms24 merged commit 223d054 into getsentry:main Jul 24, 2025
23 checks passed
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.

3 participants