-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Dynamic method/property names (static or instance) are treated as a side effect for tree shaking #3189
Comments
Yes, this is true. There are two potential evaluation points for The analysis to figure out whether an arbitrary JavaScript expression evaluation is side-effect free is complicated and is not something esbuild does. This is not a bug with esbuild. Instead it is out of scope. Also it’s not true that it’s only evaluated if the class is used. In JavaScript, computed class member names are always evaluated immediately when the class is declared. So top-level code is exactly what the method name calculation/assignment is here. |
I mean "used" in the sense of being included in the bundle. If nothing uses the class, then the class need not be declared, so how would there be a side-effect? |
Here is an example. Try running that code to see what it does. |
I understand the effect can occur if the class is used. But if I never reference the class, why would I want that side effect to occur? There doesn't seem to be any way to mark the expression "pure" -- or at least none of the ways I tried worked. Is there no way to say, "no really, this module / class / package / entire project is intended to be pure and should never bundle things (including lets, vars, and consts) that aren't explicitly referenced somewhere (and re-exporting doesn't count as a reference)?" The library I'm writing falls in its entirety under that umbrella: things not explicitly used via reference from outside the library do not need to be included in bundles built with the library as any side-effects should be suppressed when unreferenced. |
It is almost impossible to guess what side effects are intended to be kept after bundling. For example, those polyfills never gets referenced after imported, but you have to keep them anyway. So to make things at least correct, esbuild does a very careful tree-shaking.
Yep it does have some ways to do so.
You may argue that |
I'm closing this issue because esbuild is working correctly here. Using a side-effect annotation to indicate that it's ok to ignore the possibility of important side effects is required in cases like this. |
Thanks for your patience, and for explaining what's required to use PURE in this case -- I never in a million years would've guessed an IIFE was required to mark a class pure, which explains why none of the many, many ways I tried before opening this issue worked. 😉 Perhaps a future enhancement would be to allow the annotation on the line before an export or class declaration? I tried using |
At the very least, computed properties like |
Yes. That was fixed last year. See #3561. |
See this example:
Try
https://esbuild.github.io/try/#YgAwLjE4LjYAewogIGJ1bmRsZTogdHJ1ZSwKICB0cmVlU2hha2luZzogdHJ1ZSwKICBmb3JtYXQ6ICJjanMiLAogIGVudHJ5UG9pbnRzOiBbJ2VudHJ5LmpzJ10sCn0AZQBlbnRyeS5qcwBpbXBvcnQge2FsbENvbnRhaW5lcnN9IGZyb20gIi4vZmlsZSI7CmFsbENvbnRhaW5lcnMoKTsAAGZpbGUuanMAY29uc3QgdXNlID0ge21lOiAibWV0aG9kIn07CgpleHBvcnQgY2xhc3MgUGVyV2luZG93Q29tcG9uZW50IHsKICAgIFt1c2UubWVdICgpIHt9Cn0KCmV4cG9ydCBmdW5jdGlvbiBhbGxDb250YWluZXJzKCkgewp9Cgo
If you replace
[use.me]
withmethod
, the unused class is omitted from the bundle. The issue affects both static and instance methods and properties.(I'm guessing this is treating the method name calculation/assignment as if it were top-level module code, even though it's only executed if the class is actually used.)
The text was updated successfully, but these errors were encountered: