-
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
Minification causes unexpected token '{' when targetting es5 #335
Comments
Appears to happen with any commonjs import. Reduced test case:
|
esbuild/internal/printer/printer.go Lines 1500 to 1505 in 3f8508a
The args are not parenthesized in this arrow function that is being converted to a function expression. I don't have a Go compiler at my disposal, but this might do the trick:
|
Thank you so much for the report, and for the suggested fix. This should be fixed in version 0.6.26. |
@evanw A somewhat related question... Any plans to have esbuild scope hoist commonjs modules similar to rollup?
A slightly more elaborate example:
|
I have some ideas for how to do this transformation safely (AFAIK Rollup’s transformation isn’t safe because it doesn’t preserve order and may miss some exports) but they are not high priority for me. They add pretty significant complexity to linking and I’d rather spend that complexity budget on moving forward with code splitting and plugins. I don’t want to do exactly what Rollup does with trying to convert CommonJS to ESM because I want esbuild to “just work” with CommonJS modules without introducing correctness issues. Converting CommonJS to ESM is a lossy conversion because there is a semantic mismatch. FWIW my current ideas are along the lines of inlining the CommonJS closure into the first call to require for that module as long as the call to require can be made to be in its own top-level statement, and the bundler can prove that no other call to require for that module can be evaluated before the one deemed first. Then the closure would be unwrapped and the exports and/or module arguments would become top-level variables. All subsequent calls to require would just reference one of those variables. This introduces a few complexities. One is the analysis to determine whether inlining is safe. Another is that modules would no longer necessarily be contiguous in the generated code because they may be split at top-level require calls. This has implications for source maps, for example. And even with all of this complexity, it doesn’t seem like it will improve things that much, at least not with an advanced partial evaluation scheme that tries to determine if there are unreferenced object properties assigned to objects, which is a whole other level of complexity. Ultimately I see the ecosystem moving to ESM over time, which will make this less and less of an issue without needing to do this work. |
I've never encountered that. It ought to preserve side effects of modules. If the module is side effect free then it's safe to drop unused commonjs exports. If you have a failing test case please file an issue with rollup. |
I tried to look up how this transform works and I actually couldn't find any documentation (I checked here and here). So I could definitely be mistaken. Sorry if this information was incorrect. From what I understand, Rollup converts I've experienced cases where Rollup's CommonJS plugin misses exports by default. This is documented here in Rollup's documentation:
We experienced this together here where Rollup's CommonJS plugin didn't work correctly with the - commonjs(),
+ commonjs({
+ include: 'node_modules/**',
+ namedExports: {
+ react: Object.keys(react),
+ 'react-dom': Object.keys(reactDom)
+ }
+ }), I'm planning to avoid adding transforms in esbuild that require manual configuration like this. |
I see what you mean now. Yes, I agree that the various React commonjs modules are not handled well by Rollup. I wonder what Parcel does to enumerate the react exports in this scenario. |
To answer my own question, esbuild and parcel do not validate the exports of commonjs modules and will allow the import of invalid symbols - be it a typo or otherwise. Given a source file with an invalid import:
esbuild and parcel will compile it successfully and the error will only be caught at runtime:
whereas Rollup will error out in the compilation phase upon encountering the unknown import:
So while it's inconvenient to manually enumerate the exports of commonjs modules in some cases, Rollup is just being more cautious. This seems to be a different philosophical approach rather than a bug. It performs more static analysis and error checking upfront, whereas esbuild and parcel defer to flagging errors at runtime for commonjs modules. But if rollup compiles source code successfully, I'm not aware of a case where it produces incorrect code upon the import of a commonjs module. |
Dear reader, what an amazing library!
I've ran into an issue though. When I'm bundling a main.js file with imports like this:
with the following esbuild command
and open the page in safari, i get:
and in Chrome, i get just:
The relevant portion in the minified javascript looks like this:
Is this a bug or is this configuration combination not supported?
Edit: I run version 0.6.25 of esbuild
The text was updated successfully, but these errors were encountered: