-
Assigning to a
const
symbol is now an error when bundlingThis change was made because esbuild may need to change a
const
symbol into a non-constant symbol in certain situations. One situation is when the "avoid TDZ" option is enabled. Another situation is some potential upcoming changes to lazily-evaluate certain modules for code splitting purposes. Making this an error gives esbuild the freedom to do these code transformations without potentially causing problems where constants are mutated. This has already been a warning for a while so code that does this should already have been obvious. This warning was made an error in a patch release because the expectation is that no real code relies on this behavior outside of conformance tests. -
Fix for the
--keep-names
option and anonymous lowered classesThis release fixes an issue where names were not preserved for anonymous classes that contained newer JavaScript syntax when targeting an older version of JavaScript. This was because that causes the class expression to be transformed into a sequence expression, which was then not recognized as a class expression. For example, the class did not have the name
foo
in the code below when the target was set toes6
:let foo = class { #privateMethod() {} }
The
name
property of this class object is nowfoo
. -
Fix captured class names when class name is re-assigned
This fixes a corner case with class lowering to better match the JavaScript specification. In JavaScript, the body of a class statement contains an implicit constant symbol with the same name as the symbol of the class statement itself. Lowering certain class features such as private methods means moving them outside the class body, in which case the contents of the private method are no longer within the scope of the constant symbol. This can lead to a behavior change if the class is later re-assigned:
class Foo { static test() { return this.#method() } static #method() { return Foo } } let old = Foo Foo = class Bar {} console.log(old.test() === old) // This should be true
Previously this would print
false
when transformed to ES6 by esbuild. This now printstrue
. The current transformed output looks like this:var _method, method_fn; const Foo2 = class { static test() { return __privateMethod(this, _method, method_fn).call(this); } }; let Foo = Foo2; _method = new WeakSet(); method_fn = function() { return Foo2; }; _method.add(Foo); let old = Foo; Foo = class Bar { }; console.log(old.test() === old);
-
The
--allow-tdz
option is now always applied during bundlingThis option turns top-level
let
,const
, andclass
statements intovar
statements to work around some severe performance issues in the JavaScript run-time environment in Safari. Previously you had to explicitly enable this option. Now this behavior will always happen, and there is no way to turn it off. This means the--allow-tdz
option is now meaningless and no longer does anything. It will be removed in a future release. -
When bundling and minifying,
const
is now converted intolet
This was done because it's semantically equivalent but shorter. It's a valid transformation because assignment to a
const
symbol is now a compile-time error when bundling, so changingconst
tolet
should now not affect run-time behavior.