evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
38.19k stars 1.16k forks source link

Enabling tree-shaking changes position of legal comment with legal-comments=inline #3931

Open Joshix-1 opened 1 month ago

Joshix-1 commented 1 month ago

https://esbuild.github.io/try/#dAAwLjI0LjAALS1mb3JtYXQ9ZXNtIC0tbGVnYWwtY29tbWVudHM9aW5saW5lIC0tdHJlZS1zaGFraW5nPXRydWUALy8gQGxpY2Vuc2UKaW1wb3J0IHsgdGVzdCB9IGZyb20gIi9zdGF0aWMvdGVzdC5qcyIKCnRlc3QoKTs

With --tree-shaking=true the legal comment moves after the imports. With --tree-shaking=false the legal-comment stays before the import.

evanw commented 1 month ago

I don't consider this to be a bug. Enabling the esm output format with tree shaking enables some transforms including hoisting the import statements to the top of the file. In the JavaScript language, import statements have the same effect regardless of where they are in the file as long as the import statements are in the same order. Each import statement causes the imported file to be evaluated before the file containing the import. So esbuild hoisting the import statements is not a bug in that the output code is equivalent to the input code.

The reason esbuild does this is that many JavaScript transformation tools have bugs that treat import statements as happening inline instead of happening before the file is loaded, presumably due to a misunderstanding of how JavaScript works. By hoisting these imports to the top of the file, esbuild is preserving the semantics of the original code for these buggy tools.

When you enable inline legal comments, esbuild treats legal comments in statement position as statements and keeps them in the AST wherever they were authored. They are not considered to be attached to anything, and are not intended to be used as annotations on the following statement. They are only meant to be used as legal comments (to ensure that the notice about the license they represent ends up in the output file). So esbuild hoisting import statements past other statements to the top of the file is not a bug, even if some of those other statements happen to be legal comment statements.

Joshix-1 commented 1 month ago

I want to have a // @license comment at the start of the first line of the generated javascript files (partly because LibreJs doesn't recognize it otherwise [I'm adding the required end comment with '--footer:js=// @license-end']).

A --legal-comments=start-of-file would also solve it for me. Adding the comment with --banner doesn't work for me as I have scripts with different licenses.