v0.15.8
-
Fix JSX name collision edge case (#2534)
Code generated by esbuild could have a name collision in the following edge case:
- The JSX transformation mode is set to
automatic
, which causesimport
statements to be inserted - An element uses a
{...spread}
followed by akey={...}
, which uses the legacycreateElement
fallback imported fromreact
- Another import uses a name that ends with
react
such as@remix-run/react
- The output format has been set to CommonJS so that
import
statements are converted into require calls
In this case, esbuild previously generated two variables with the same name
import_react
, like this:var import_react = require("react"); var import_react2 = require("@remix-run/react");
That bug is fixed in this release. The code generated by esbuild no longer contains a name collision.
- The JSX transformation mode is set to
-
Fall back to WebAssembly on Android ARM (#1556, #1578, #2335, #2526)
Go's compiler supports trivial cross-compiling to almost all platforms without installing any additional software other than the Go compiler itself. This has made it very easy for esbuild to publish native binary executables for many platforms. However, it strangely doesn't support cross-compiling to Android ARM without installing the Android build tools.
So instead of publishing a native esbuild binary executable to npm, this release publishes a WebAssembly fallback build. This is essentially the same as the
esbuild-wasm
package but it's installed automatically when you install theesbuild
package on Android ARM. So packages that depend on theesbuild
package should now work on Android ARM. This change has not yet been tested end-to-end because I don't have a 32-bit Android ARM device myself, but in theory it should work.This inherits the drawbacks of WebAssembly including significantly slower performance than native as well as potentially also more severe memory usage limitations and lack of certain features (e.g.
--serve
). If you want to use a native binary executable of esbuild on Android ARM, you may be able to build it yourself from source after installing the Android build tools. -
Attempt to better support Yarn's
ignorePatternData
feature (#2495)Part of resolving paths in a project using Yarn's Plug'n'Play feature involves evaluating a regular expression in the
ignorePatternData
property of.pnp.data.json
. However, it turns out that the particular regular expressions generated by Yarn use some syntax that works with JavaScript regular expressions but that does not work with Go regular expressions.In this release, esbuild will now strip some of the the problematic syntax from the regular expression before compiling it, which should hopefully allow it to be compiled by Go's regular expression engine. The specific character sequences that esbuild currently strips are as follows:
(?!\.)
(?!(?:^|\/)\.)
(?!\.{1,2}(?:\/|$))
(?!(?:^|\/)\.{1,2}(?:\/|$))
These seem to be used by Yarn to avoid the
.
and..
path segments in the middle of relative paths. The removal of these character sequences seems relatively harmless in this case since esbuild shouldn't ever generate such path segments. This change should add support to esbuild for Yarn'spnpIgnorePatterns
feature. -
Fix non-determinism issue with legacy block-level function declarations and strict mode (#2537)
When function declaration statements are nested inside a block in strict mode, they are supposed to only be available within that block's scope. But in "sloppy mode" (which is what non-strict mode is commonly called), they are supposed to be available within the whole function's scope:
// This returns 1 due to strict mode function test1() { 'use strict' function fn() { return 1 } if (true) { function fn() { return 2 } } return fn() } // This returns 2 due to sloppy mode function test2() { function fn() { return 1 } if (true) { function fn() { return 2 } } return fn() }
To implement this, esbuild compiles these two functions differently to reflect their different semantics:
function test1() { "use strict"; function fn() { return 1; } if (true) { let fn2 = function() { return 2; }; } return fn(); } function test2() { function fn() { return 1; } if (true) { let fn2 = function() { return 2; }; var fn = fn2; } return fn(); }
However, the compilation had a subtle bug where the automatically-generated function-level symbols for multible hoisted block-level function declarations in the same block a sloppy-mode context were generated in a random order if the output was in strict mode, which could be the case if TypeScript's
alwaysStrict
setting was set to true. This lead to non-determinism in the output as the minifier would randomly exchange the generated names for these symbols on different runs. This bug has been fixed by sorting the keys of the unordered map before iterating over them. -
Fix parsing of
@keyframes
with string identifiers (#2555)Firefox supports
@keyframes
with string identifier names. Previously this was treated as a syntax error by esbuild as it doesn't work in any other browser. The specification allows for this however, so it's technically not a syntax error (even though it would be unwise to use this feature at the moment). There was also a bug where esbuild would remove the identifier name in this case as the syntax wasn't recognized.This release changes esbuild's parsing of
@keyframes
to now consider this case to be an unrecognized CSS rule. That means it will be passed through unmodified (so you can now use esbuild to bundle this Firefox-specific CSS) but the CSS will not be pretty-printed or minified. I don't think it makes sense for esbuild to have special code to handle this Firefox-specific syntax at this time. This decision can be revisited in the future if other browsers add support for this feature. -
Add the
--jsx-side-effects
API option (#2539, #2546)By default esbuild assumes that JSX expressions are side-effect free, which means they are annoated with
/* @__PURE__ */
comments and are removed during bundling when they are unused. This follows the common use of JSX for virtual DOM and applies to the vast majority of JSX libraries. However, some people have written JSX libraries that don't have this property. JSX expressions can have arbitrary side effects and can't be removed. If you are using such a library, you can now pass--jsx-side-effects
to tell esbuild that JSX expressions have side effects so it won't remove them when they are unused.This feature was contributed by @rtsao.