-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Empty init functions generated for side-effect-free ESM modules #3771
Comments
The Example of namespace capturing in ESM context. // However, esbuild does know the namespace object is PURE, so if you never used the object it will be tree-shaked. Example of using |
I see, so it depends on the style of import where the module is imported, not so much the module itself. Here is a full representation of my scenario, btw. When you say "namespace object", I think you are referring to the "module object" in the case of ESM and the value of I still don't quite understand, though, because Furthermore, it is a complete no-op. It was generated by esbuild as an empty function so surely esbuild can know it is a no-op and omit it? |
Yes, my wording might not be very correct. esbuild bundle works by scanning the code in 2 phases. The first phase is gathering and transforming input files in parallel (that's why it is fast). The second phase is linking these individual modules, performing scope hoisting and generating esm-cjs interop helpers. I guess when esbuild see your wrapper.cts, it knows:
Therefore, it can prepare such template for wrapper.cts: // prepare a commonjs module object
var require_wrapper = __commonJS {
// evaluating dependencies to make sure
// any possible side effect evaluates before this module
init_is_equal();
... // rest of the module's content
}; During the second phase, the linker just has to make sure these variables are bound. There's no further side-effect tracking algorithm performed on them. It might be diffcult to adding such optimization during the linking phase without hurting the speed. |
Ok while there is opportunity to optimise the output I understand your explanation, thanks! |
ESBuild seems to generate empty "module init" functions even for side-effect free ESM modules.
Given a module
src/utils/is-equal.mts
:What ends up in the generated bundle is (in the root scope):
And then
init_is_equal
is called everywhere thatisEqual
is imported. What is causing this? I would not expectinit_is_equal
to be present. It does this for some modules but not others.Config
platform: 'node', format: 'esm', target: 'node20'
"sideEffects: false"
inpackage.json
) but some dependencies are CJSThe text was updated successfully, but these errors were encountered: