This repository has been archived by the owner on May 22, 2024. It is now read-only.
fix(deps): update dependency esbuild to v0.12.3 #480
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.11.10
->0.12.3
Release Notes
evanw/esbuild
v0.12.3
Compare Source
Ensure JSX element names start with a capital letter (#1309)
The JSX specification only describes the syntax and says nothing about how to interpret it. But React (and therefore esbuild) treats JSX tags that start with a lower-case ASCII character as strings instead of identifiers. That way the tag
<i/>
always refers to the italic HTML elementi
and never to a local variable namedi
.However, esbuild may rename identifiers for any number of reasons such as when minification is enabled. Previously esbuild could sometimes rename identifiers used as tag names such that they start with a lower-case ASCII character. This is problematic when JSX syntax preservation is enabled since subsequent JSX processing would then turn these identifier references into strings.
With this release, esbuild will now make sure identifiers used in tag names start with an upper-case ASCII character instead when JSX syntax preservation is enabled. This should avoid problems when using esbuild with JSX transformation tools.
Fix a single hyphen being treated as a CSS name (#1310)
CSS identifiers are allowed to start with a
-
character if (approximately) the following character is a letter, an escape sequence, a non-ASCII character, the character_
, or another-
character. This check is used in certain places when printing CSS to determine whether a token is a valid identifier and can be printed as such or whether it's an invalid identifier and needs to be quoted as a string. One such place is in attribute selectors such as[a*=b]
.However, esbuild had a bug where a single
-
character was incorrectly treated as a valid identifier in this case. This is because the end of string became U+FFFD (the Unicode replacement character) which is a non-ASCII character and a valid name-start code point. With this release a single-
character is no longer treated as a valid identifier. This fix was contributed by @lbwa.v0.12.2
Compare Source
Fix various code generation and minification issues (#1305)
This release fixes the following issues, which were all identified by running esbuild against the latest UglifyJS test suite:
The
in
operator is now surrounded parentheses inside arrow function expression bodies insidefor
loop initializers:Without this, the
in
operator would cause the for loop to be considered a for-in loop instead.The statement
return undefined;
is no longer minified toreturn;
inside async generator functions:Using
return undefined;
inside an async generator function has the same effect asreturn await undefined;
which schedules a task in the event loop and runs code in a different order than justreturn;
, which doesn't hide an implicitawait
expression.Property access expressions are no longer inlined in template tag position:
The expression
a.b`c`
is different than the expression(0, a.b)`c`
. The first calls the functiona.b
witha
as the value forthis
but the second calls the functiona.b
with the default value forthis
(the global object in non-strict mode orundefined
in strict mode).Verbatim
__proto__
properties inside object spread are no longer inlined when minifying:A verbatim (i.e. non-computed non-method) property called
__proto__
inside an object literal actually sets the prototype of the surrounding object literal. It does not add an "own property" called__proto__
to that object literal, so inlining it into the parent object literal would be incorrect. The presence of a__proto__
property now stops esbuild from applying the object spread inlining optimization when minifying.The value of
this
has now been fixed for lowered private class members that are used as template tags:The value of
this
here should be an instance of the class because the template tag is a property access expression. However, it was previously the default value (the global object in non-strict mode orundefined
in strict mode) instead due to the private member transformation, which is incorrect.Invalid escape sequences are now allowed in tagged template literals
This implements the template literal revision feature: https://github.com/tc39/proposal-template-literal-revision. It allows you to process tagged template literals using custom semantics that don't follow JavaScript escape sequence rules without causing a syntax error:
v0.12.1
Compare Source
Add the ability to preserve JSX syntax (#735)
You can now pass
--jsx=preserve
to esbuild to prevent JSX from being transformed into JS. Instead, JSX syntax in all input files is preserved throughout the pipeline and is printed as JSX syntax in the generated output files. Note that this means the output files are no longer valid JavaScript code if you enable this setting. This feature is intended to be used when you want to transform the JSX syntax in esbuild's output files by another tool after bundling, usually one with a different JSX-to-JS transform than the one esbuild implements.Update the list of built-in node modules (#1294)
The list of built-in modules that come with node was outdated, so it has been updated. It now includes new modules such as
wasi
and_http_common
. Modules in this list are automatically marked as external when esbuild's platform is configured tonode
.v0.12.0
Compare Source
This release contains backwards-incompatible changes. Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as recommended by npm). You should either be pinning the exact version of
esbuild
in yourpackage.json
file or be using a version range syntax that only accepts patch upgrades such as~0.11.0
. See the documentation about semver for more information.The breaking changes in this release relate to CSS import order and also build scenarios where both the
inject
anddefine
API options are used (see below for details). These breaking changes are as follows:Fix bundled CSS import order (#465)
JS and CSS use different import ordering algorithms. In JS, importing a file that has already been imported is a no-op but in CSS, importing a file that has already been imported re-imports the file. A simple way to imagine this is to view each
@import
rule in CSS as being replaced by the contents of that file similar to#include
in C/C++. However, this is incorrect in the case of@import
cycles because it would cause infinite expansion. A more accurate way to imagine this is that in CSS, a file is evaluated at the last@import
location while in JS, a file is evaluated at the firstimport
location.Previously esbuild followed JS import order rules for CSS but now esbuild will follow CSS import order rules. This is a breaking change because it means your CSS may behave differently when bundled. Note that CSS import order rules are somewhat unintuitive because evaluation order matters. In CSS, using
@import
multiple times can end up unintentionally erasing overriding styles. For example, consider the following files:Because of how CSS import order works,
entry.css
will now be bundled like this:This means the body will unintuitively be all black! The file
reset.css
is evaluated at the location of the last@import
instead of the first@import
. The fix for this case is to remove the nested imports ofreset.css
and to importreset.css
exactly once at the top ofentry.css
.Note that while the evaluation order of external CSS imports is preserved with respect to other external CSS imports, the evaluation order of external CSS imports is not preserved with respect to other internal CSS imports. All external CSS imports are "hoisted" to the top of the bundle. The alternative would be to generate many smaller chunks which is usually undesirable. So in this case esbuild's CSS bundling behavior will not match the browser.
Fix bundled CSS when using JS code splitting (#608)
Previously esbuild generated incorrect CSS output when JS code splitting was enabled and the JS code being bundled imported CSS files. CSS code that was reachable via multiple JS entry points was split off into a shared CSS chunk, but that chunk was not actually imported anywhere so the shared CSS was missing. This happened because both CSS and JS code splitting were experimental features that are still in progress and weren't tested together.
Now esbuild's CSS output should contain all reachable CSS code when JS code splitting is enabled. Note that this does not mean code splitting works for CSS files. Each CSS output file simply contains the transitive set of all CSS reachable from the JS entry point including through dynamic
import()
andrequire()
expressions. Specifically, the bundler constructs a virtual CSS file for each JS entry point consisting only of@import
rules for each CSS file imported into a JS file. These@import
rules are constructed in JS source order, but then the bundler uses CSS import order from that point forward to bundle this virtual CSS file into the final CSS output file.This model makes the most sense when CSS files are imported into JS files via JS
import
statements. Importing CSS viaimport()
andrequire()
(either directly or transitively through multiple intermediate JS files) should still "work" in the sense that all reachable CSS should be included in the output, but in this case esbuild will pick an arbitrary (but consistent) import order. The import order may not match the order that the JS files are evaluated in because JS evaluation order of dynamic imports is only determined at run-time while CSS bundling happens at compile-time.It's possible to implement code splitting for CSS such that CSS code used between multiple entry points is shared. However, CSS lacks a mechanism for "lazily" importing code (i.e. disconnecting the import location with the evaluation location) so CSS code splitting could potentially need to generate a huge number of very small chunks to preserve import order. It's unclear if this would end up being a net win or not as far as browser download time. So sharing-based code splitting is currently not supported for CSS.
It's theoretically possible to implement code splitting for CSS such that CSS from a dynamically-imported JS file (e.g. via
import()
) is placed into a separate chunk. However, due to how@import
order works this would in theory end up re-evaluating all shared dependencies which could overwrite overloaded styles and unintentionally change the way the page is rendered. For example, constructing a single-page app architecture such that each page is JS-driven and can transition to other JS-driven pages viaimport()
could end up with pages that look different depending on what order you visit them in. This is clearly undesirable. The simple way to address this is to just not support dynamic-import code splitting for CSS either.Change "define" to have higher priority than "inject" (#660)
The "define" and "inject" features are both ways of replacing certain expressions in your source code with other things expressions. Previously esbuild's behavior ran "inject" before "define", which could lead to some undesirable behavior. For example (from the
react
npm package):If you use "define" to replace
process.env.NODE_ENV
with"production"
and "inject" to replaceprocess
with a shim that emulates node's process API, thenprocess
was previously replaced first and thenprocess.env.NODE_ENV
wasn't matched becauseprocess
referred to the injected shim. This wasn't ideal because it means esbuild didn't detect the branch condition as a constant (since it doesn't know how the shim behaves at run-time) and bundled both the development and production versions of the package.With this release, esbuild will now run "define" before "inject". In the above example this means that
process.env.NODE_ENV
will now be replaced with"production"
, the injected shim will not be included, and only the production version of the package will be bundled. This feature was contributed by @rtsao.In addition to the breaking changes above, the following features are also included in this release:
Add support for the
NO_COLOR
environment variableThe CLI will now omit color if the
NO_COLOR
environment variable is present, which is an existing convention that is followed by some other software. See https://no-color.org/ for more information.v0.11.23
Compare Source
Add a shim function for unbundled uses of
require
(#1202)Modules in CommonJS format automatically get three variables injected into their scope:
module
,exports
, andrequire
. These allow the code to import other modules and to export things from itself. The bundler automatically rewrites uses ofmodule
andexports
to refer to the module's exports and certain uses ofrequire
to a helper function that loads the imported module.Not all uses of
require
can be converted though, and un-converted uses ofrequire
will end up in the output. This is problematic becauserequire
is only present at run-time if the output is run as a CommonJS module. Otherwiserequire
is undefined, which means esbuild's behavior is inconsistent between compile-time and run-time. Themodule
andexports
variables are objects at compile-time and run-time butrequire
is a function at compile-time and undefined at run-time. This causes code that checks fortypeof require
to have inconsistent behavior:In the above example, ideally
CommonJS detected
would always be printed since the code is being bundled with a CommonJS-aware bundler. To fix this, esbuild will now substitute references torequire
with a stub__require
function when bundling if the output format is something other than CommonJS. This should ensure thatrequire
is now consistent between compile-time and run-time. When bundled, code that uses unbundled references torequire
will now look something like this:Fix incorrect caching of internal helper function library (#1292)
This release fixes a bug where running esbuild multiple times with different configurations sometimes resulted in code that would crash at run-time. The bug was introduced in version 0.11.19 and happened because esbuild's internal helper function library is parsed once and cached per configuration, but the new profiler name option was accidentally not included in the cache key. This option is now included in the cache key so this bug should now be fixed.
Minor performance improvements
This release contains some small performance improvements to offset an earlier minor performance regression due to the addition of certain features such as hashing for entry point files. The benchmark times on the esbuild website should now be accurate again (versions of esbuild after the regression but before this release were slightly slower than the benchmark).
v0.11.22
Compare Source
Add support for the "import assertions" proposal
This is new JavaScript syntax that was shipped in Chrome 91. It looks like this:
On the web, the content type for a given URL is determined by the
Content-Type
HTTP header instead of the file extension. So adding support for importing non-JS content types such as JSON to the web could cause security issues since importing JSON from an untrusted source is safe while importing JS from an untrusted source is not.Import assertions are a new feature to address this security concern and unblock non-JS content types on the web. They cause the import to fail if the
Content-Type
header doesn't match the expected value. This prevents security issues for data-oriented content types such as JSON since it guarantees that data-oriented content will never accidentally be evaluated as code instead of data. More information about the proposal is available here: https://github.com/tc39/proposal-import-assertions.This release includes support for parsing and printing import assertions. They will be printed if the configured target environment supports them (currently only in
esnext
andchrome91
), otherwise they will be omitted. If they aren't supported in the configured target environment and it's not possible to omit them, which is the case for certain dynamicimport()
expressions, then using them is a syntax error. Import assertions are otherwise unused by the bundler.Forbid the token sequence
for ( async of
when not followed by=>
This follows a recently-fixed ambiguity in the JavaScript specification, which you can read about here: Normative: forbid for-of loops with variable named async tc39/ecma262#2256. Prior to this change in the specification, it was ambiguous whether this token sequence should be parsed as
for ( async of =>
orfor ( async of ;
. V8 and esbuild expected=>
afterfor ( async of
while SpiderMonkey and JavaScriptCore did something else.The ambiguity has been removed and the token sequence
for ( async of
is now forbidden by the specification when not followed by=>
, so esbuild now forbids this as well. Note that the token sequencefor await (async of
is still allowed even when not followed by=>
. Code such asfor ((async) of []) ;
is still allowed and will now be printed with parentheses to avoid the grammar ambiguity.Restrict
super
property access to inside of methodsYou can now only use
super.x
andsuper[x]
expressions inside of methods. Previously these expressions were incorrectly allowed everywhere. This means esbuild now follows the JavaScript language specification more closely.v0.11.21
Compare Source
TypeScript
override
for parameter properties (#1262)You can now use the
override
keyword instead of or in addition to thepublic
,private
,protected
, andreadonly
keywords for declaring a TypeScript parameter property:This feature was recently added to the TypeScript compiler and will presumably be in an upcoming version of the TypeScript language. Support for this feature in esbuild was contributed by @g-plane.
Fix duplicate export errors due to TypeScript import-equals statements (#1283)
TypeScript has a special import-equals statement that is not part of JavaScript. It looks like this:
Each import can be a type or a value and type-only imports need to be eliminated when converting this code to JavaScript, since types do not exist at run-time. The TypeScript compiler generates the following JavaScript code for this example:
The
x
,y
, andz
import statements are eliminated in esbuild by iterating over imports and exports multiple times and continuing to remove unused TypeScript import-equals statements until none are left. The first pass removesz
and marksy
as unused, the second pass removesy
and marksx
as unused, and the third pass removesx
.However, this had the side effect of making esbuild incorrectly think that a single export is exported twice (because it's processed more than once). This release fixes that bug by only iterating multiple times over imports, not exports. There should no longer be duplicate export errors for this case.
Add support for type-only TypeScript import-equals statements (#1285)
This adds support for the following new TypeScript syntax that was added in version 4.2:
Unlike
import React = require('react')
, this statement is a type declaration instead of a value declaration and should be omitted from the generated code. See microsoft/TypeScript#41573 for details. This feature was contributed by @g-plane.v0.11.20
Compare Source
Omit warning about duplicate JSON keys from inside
node_modules
(#1254)This release no longer warns about duplicate keys inside
package.json
files insidenode_modules
. There are packages like this that are published to npm, and this warning is unactionable. Now esbuild will only issue this warning outside ofnode_modules
directories.Add CSS minification for
box-shadow
valuesThe CSS
box-shadow
property is now minified when--mangle-syntax
is enabled. This includes trimming length values and minifying color representations.Fix object spread transform for non-spread getters (#1259)
When transforming an object literal containing object spread (the
...
syntax), properties inside the spread should be evaluated but properties outside the spread should not be evaluated. Previously esbuild's object spread transform incorrectly evaluated properties in both cases. Consider this example:This should print out
1 2 3
because the non-spread getter should not be evaluated. Instead, esbuild was incorrectly transforming this into code that printed1 3 2
. This issue should now be fixed with this release.Prevent private class members from being added more than once
This fixes a corner case with the private class member implementation. Constructors in JavaScript can return an object other than
this
, so private class members can actually be added to objects other thanthis
. This can be abused to attach completely private metadata to other objects:This already worked in code transformed by esbuild for older browsers. However, calling
new Derived(foo)
multiple times in the above code was incorrectly allowed. This should not be allowed because it would mean that the private field#y
would be re-declared. This is no longer allowed starting from this release.v0.11.19
Compare Source
Allow esbuild to be restarted in Deno (#1238)
The esbuild API for Deno has an extra function called
stop()
that doesn't exist in esbuild's API for node. This is because Deno doesn't provide a way to stop esbuild automatically, so callingstop()
is required to allow Deno to exit. However, once stopped the esbuild API could not be restarted.With this release, you can now continue to use esbuild after calling
stop()
. This will restart esbuild's API and means that you will need to callstop()
again for Deno to be able to exit. This feature was contributed by @lucacasonato.Fix code splitting edge case (#1252)
This release fixes an edge case where bundling with code splitting enabled generated incorrect code if multiple ESM entry points re-exported the same re-exported symbol from a CommonJS file. In this case the cross-chunk symbol dependency should be the variable that holds the return value from the
require()
call instead of the original ESM namedimport
clause item. When this bug occurred, the generated ESM code contained an export and import for a symbol that didn't exist, which caused a module initialization error. This case should now work correctly.Fix code generation with
declare
class fields (#1242)This fixes a bug with TypeScript code that uses
declare
on a class field and yourtsconfig.json
file has"useDefineForClassFields": true
. Fields marked asdeclare
should not be defined in the generated code, but they were incorrectly being declared asundefined
. These fields are now correctly omitted from the generated code.Annotate module wrapper functions in debug builds (#1236)
Sometimes esbuild needs to wrap certain modules in a function when bundling. This is done both for lazy evaluation and for CommonJS modules that use a top-level
return
statement. Previously these functions were all anonymous, so stack traces for errors thrown during initialization looked like this:This release adds names to these anonymous functions when minification is disabled. The above stack trace now looks like this:
This is similar to Webpack's development-mode behavior:
These descriptive function names will additionally be available when using a profiler such as the one included in the "Performance" tab in Chrome Developer Tools. Previously all functions were named
(anonymous)
which made it difficult to investigate performance issues during bundle initialization.Add CSS minification for more cases
The following CSS minification cases are now supported:
The CSS
margin
property family is now minified including combining themargin-top
,margin-right
,margin-bottom
, andmargin-left
properties into a singlemargin
property.The CSS
padding
property family is now minified including combining thepadding-top
,padding-right
,padding-bottom
, andpadding-left
properties into a singlepadding
property.The CSS
border-radius
property family is now minified including combining theborder-top-left-radius
,border-top-right-radius
,border-bottom-right-radius
, andborder-bottom-left-radius
properties into a singleborder-radius
property.The four special pseudo-elements
::before
,::after
,::first-line
, and::first-letter
are allowed to be parsed with one:
for legacy reasons, so the::
is now converted to:
for these pseudo-elements.Duplicate CSS rules are now deduplicated. Only the last rule is kept, since that's the only one that has any effect. This applies for both top-level rules and nested rules.
Preserve quotes around properties when minification is disabled (#1251)
Previously the parser did not distinguish between unquoted and quoted properties, since there is no semantic difference. However, some tools such as Google Closure Compiler with "advanced mode" enabled attach their own semantic meaning to quoted properties, and processing code intended for Google Closure Compiler's advanced mode with esbuild was changing those semantics. The distinction between unquoted and quoted properties is now made in the following cases:
The parser will now preserve the quoted properties in these cases as long as
--minify-syntax
is not enabled. This does not mean that esbuild is officially supporting Google Closure Compiler's advanced mode, just that quoted properties are now preserved when the AST is pretty-printed. Google Closure Compiler's advanced mode accepts a language that shares syntax with JavaScript but that deviates from JavaScript semantics and there could potentially be other situations where preprocessing code intended for Google Closure Compiler's advanced mode with esbuild first causes it to break. If that happens, that is not a bug with esbuild.v0.11.18
Compare Source
Add support for OpenBSD on x86-64 (#1235)
Someone has asked for OpenBSD to be supported on x86-64. It should now be supported starting with this release.
Fix an incorrect warning about top-level
this
This was introduced in the previous release, and happens when using a top-level
async
arrow function with a compilation target that doesn't support it. The reason is that doing this generates a shim that preserves the value ofthis
. However, this warning message is confusing because there is not necessarily anythis
present in the source code. The warning message has been removed in this case. Now it should only show up ifthis
is actually present in the source code.v0.11.17
Compare Source
Fix building with a large
stdin
string with Deno (#1219)When I did the initial port of esbuild's node-based API to Deno, I didn't realize that Deno's
write(bytes)
function doesn't actually write the provided bytes. Instead it may only write some of those bytes and needs to be repeatedly called again until it writes everything. This meant that calling esbuild's Deno-based API could hang if the API request was large enough, which can happen in practice when using thestdin
string feature. Thewrite
API is now called in a loop so these hangs in Deno should now be fixed.Add a warning about replacing
this
withundefined
in ESM code (#1225)There is existing JavaScript code that sometimes references top-level
this
as a way to access the global scope. However, top-levelthis
is actually specified to beundefined
inside of ECMAScript module code, which makes referencing top-levelthis
inside ESM code useless. This issue can come up when the existing JavaScript code is adapted for ESM by addingimport
and/orexport
. All top-level references tothis
are replaced withundefined
when bundling to make sure ECMAScript module behavior is emulated correctly regardless of the environment in which the resulting code is run.With this release, esbuild will now warn about this when bundling:
This warning is not unique to esbuild. Rollup also already has a similar warning:
Allow a string literal as a JSX fragment (#1217)
TypeScript's JSX implementation allows you to configure a custom JSX factory and a custom JSX fragment, but requires that they are both valid JavaScript identifier member expression chains. Since esbuild's JSX implementation is based on TypeScript, esbuild has the same requirement. So
React.createElement
is a valid JSX factory value but['React', 'createElement']
is not.However, the Mithril framework has decided to use
"["
as a JSX fragment, which is not a valid JavaScript identifier member expression chain. This meant that using Mithril with esbuild required a workaround. In this release, esbuild now lets you use a string literal as a custom JSX fragment. It should now be easier to use esbuild's JSX implementation with libraries such as Mithril.Fix
metafile
inonEnd
withwatch
mode enabled (#1186)This release fixes a bug where the
metafile
property was incorrectly undefined inside pluginonEnd
callbacks ifwatch
mode is enabled for all builds after the first build. Themetafile
property was accidentally being set after callingonEnd
instead of before.v0.11.16
Compare Source
Fix TypeScript
enum
edge case (#1198)In TypeScript, you can reference the inner closure variable in an
enum
within the inner closure by name:The TypeScript compiler generates the following code for this case:
However, TypeScript also lets you declare an
enum
value with the same name as the inner closure variable. In that case, the value "shadows" the declaration of the inner closure variable:The TypeScript compiler generates the following code for this case:
Previously esbuild reported a duplicate variable declaration error in the second case due to the collision between the
enum
value and the inner closure variable with the same name. With this release, the shadowing is now handled correctly.Parse the
@-moz-document
CSS rule (#1203)This feature has been removed from the web because it's actively harmful, at least according to this discussion. However, there is one exception where
@-moz-document url-prefix() {
is accepted by Firefox to basically be an "if Firefox" conditional rule. Because of this, esbuild now parses the@-moz-document
CSS rule. This should result in better pretty-printing and minification and no more warning when this rule is used.Fix syntax error in TypeScript-specific speculative arrow function parsing (#1211)
Because of grammar ambiguities, expressions that start with a parenthesis are parsed using what's called a "cover grammar" that is a super-position of both a parenthesized expression and an arrow function parameter list. In JavaScript, the cover grammar is unambiguously an arrow function if and only if the following token is a
=>
token.But in TypeScript, the expression is still ambiguously a parenthesized expression or an arrow function if the following token is a
:
since it may be the second half of the?:
operator or a return type annotation. This requires speculatively attempting to reduce the cover grammar to an arrow function parameter list.However, when doing this esbuild eagerly reported an error if a default argument was encountered and the target is
es5
(esbuild doesn't support lowering default arguments to ES5). This is problematic in the following TypeScript code since the parenthesized code turns out to not be an arrow function parameter list:Previously this code incorrectly generated an error since
hover = 2
was incorrectly eagerly validated as a default argument. With this release, the reporting of the default argument error when targetinges5
is now done lazily and only when it's determined that the parenthesized code should actually be interpreted as an arrow function parameter list.Further changes to the behavior of the
browser
field (#1209)This release includes some changes to how the
browser
field inpackage.json
is interpreted to better match how Browserify, Webpack, Parcel, and Rollup behave. The interpretation of this map in esbuild is intended to be applied if and only if it's applied by any one of these bundlers. However, there were some cases where esbuild applied the mapping and none of the other bundlers did, which could lead to build failures. These cases have been added to my growing list ofbrowser
field test cases and esbuild's behavior should now be consistent with other bundlers again.Avoid placing a
super()
call inside areturn
statement (#1208)When minification is enabled, an expression followed by a return statement (e.g.
a(); return b
) is merged into a single statement (e.g.return a(), b
). This is done because it sometimes results in smaller code. If the return statement is the only statement in a block and the block is in a single-statement context, the block can be removed which saves a few characters.Previously esbuild applied this rule to calls to
super()
inside of constructors. Doing that broke esbuild's class lowering transform that tries to insert class field initializers after thesuper()
call. This transform isn't robust and only scans the top-level statement list inside the constructor, so inserting thesuper()
call inside of thereturn
statement means class field initializers were inserted before thesuper()
call instead of after. This could lead to run-time crashes due to initialization failure.With this release, top-level calls to
super()
will no longer be placed insidereturn
statements (in addition to various other kinds of statements such asthrow
, which are now also handled). This should avoid class field initializers being inserted before thesuper()
call.Fix a bug with
onEnd
and watch mode (#1186)This release fixes a bug where
onEnd
plugin callbacks only worked with watch mode when anonRebuild
watch mode callback was present. NowonEnd
callbacks should fire even if there is noonRebuild
callback.Fix an edge case with minified export names and code splitting (#1201)
The names of symbols imported from other chunks were previously not considered for renaming during minified name assignment. This could cause a syntax error due to a name collision when two symbols have the same original name. This was just an oversight and has been fixed, so symbols imported from other chunks should now be renamed when minification is enabled.
Provide a friendly error message when you forget
async
(#1216)If the parser hits a parse error inside a non-asynchronous function or arrow expression and the previous token is
await
, esbuild will now report a friendly error about a missingasync
keyword instead of reporting the parse error. This behavior matches other JavaScript parsers including TypeScript, Babel, and V8.The previous error looked like this:
The error now looks like this:
v0.11.15
Compare Source
Provide options for how to handle legal comments (#919)
A "legal comment" is considered to be any comment that contains
@license
or@preserve
or that starts with//!
or/*!
. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code.However, some people want to remove the automatically-generated license information before they distribute their code. To facilitate this, esbuild now provides several options for how to handle legal comments (via
--legal-comments=
in the CLI andlegalComments
in the JS API):none
: Do not preserve any legal commentsinline
: Preserve all statement-level legal commentseof
: Move all statement-level legal comments to the end of the filelinked
: Move all statement-level legal comments to a.LEGAL.txt
file and link to them with a commentexternal
: Move all statement-level legal comments to a.LEGAL.txt
file but to not link to themThe default behavior is
eof
when bundling andinline
otherwise.Add
onStart
andonEnd
callbacks to the plugin APIPlugins can now register callbacks to run when a build is started and ended:
One benefit of
onStart
andonEnd
is that they are run for all builds including rebuilds (relevant for incremental mode, watch mode, or serve mode), so they should be a good place to do work related to the build lifecycle.More details:
build.onStart()
You should not use an
onStart
callback for initialization since it can be run multiple times. If you want to initialize something, just put your plugin initialization code directly inside thesetup
function instead.The
onStart
callback can beasync
and can return a promise. However, the build does not wait for the promise to be resolved before starting, so a slowonStart
callback will not necessarily slow down the build. AllonStart
callbacks are also run concurrently, not consecutively. The returned promise is purely for error reporting, and matters when theonStart
callback needs to do an asynchronous operation that may fail. If your plugin needs to wait for an asynchronous task inonStart
to complete before anyonResolve
oronLoad
callbacks are run, you will need to have youronResolve
oronLoad
callbacks block on that task fromonStart
.Note that
onStart
callbacks do not have the ability to mutatebuild.initialOptions
. The initial options can only be modified within thesetup
function and are consumed once thesetup
function returns. All rebuilds use the same initial options so the initial options are never re-consumed, and modifications tobuild.initialOptions
that are done withinonStart
are ignored.build.onEnd()
All
onEnd
callbacks are run in serial and each callback is given access to the final build result. It can modify the build result before returning and can delay the end of the build by returning a promise. If you want to be able to inspect the build graph, you should setbuild.initialOptions.metafile = true
and the build graph will be returned as themetafile
property on the build result object.v0.11.14
Compare Source
Implement arbitrary module namespace identifiers
This introduces new JavaScript syntax:
The proposal for this feature appears to not be going through the regular TC39 process. It is being done as a subtle direct pull request instead. It seems appropriate for esbuild to support this feature since it has been implemented in V8 and has now shipped in Chrome 90 and node 16.
According to the proposal, this feature is intended to improve interop with non-JavaScript languages which use exports that aren't valid JavaScript identifiers such as
Foo::~Foo
. In particular, WebAssembly allows any valid UTF-8 string as to be used as an export alias.This feature was actually already partially possible in previous versions of JavaScript via the computed property syntax:
However, doing this is very un-ergonomic and exporting something as an arbitrary name is impossible outside of
export * from
. So this proposal is designed to fully fill out the possibility matrix and make arbitrary alias names a proper first-class feature.Implement more accurate
sideEffects
behavior from Webpack (#1184)This release adds support for the implicit
**/
prefix that must be added to paths in thesideEffects
array inpackage.json
if the path does not contain/
. Another way of saying this is ifpackage.json
contains asideEffects
array with a string that doesn't contain a/
then it should be treated as a file name instead of a path. Previously esbuild treated all strings in this array as paths, which does not match how Webpack behaves. The result of this meant that esbuild could consider files to have no side effects while Webpack would consider the same files to have side effects. This bug should now be fixed.v0.11.13
Compare Source
Implement ergonomic brand checks for private fields
This introduces new JavaScript syntax:
The TC39 proposal for this feature is currently at stage 3 but has already been shipped in Chrome 91 and has also landed in Firefox. It seems reasonably inevitable given that it's already shipping and that it's a very simple feature, so it seems appropriate to add this feature to esbuild.
Add the
--allow-overwrite
flag (#1152)This is a new flag that allows output files to overwrite input files. It's not enabled by default because doing so means overwriting your source code, which can lead to data loss if your code is not checked in. But supporting this makes certain workflows easier by avoiding the need for a temporary directory so doing this is now supported.
Minify property accesses on object literals (#1166)
The code
{a: {b: 1}}.a.b
will now be minified to1
. This optimization is relatively complex and hard to do safely. Here are some tricky cases that are correctly handled:Improve arrow function parsing edge cases
There are now more situations where arrow expressions are not allowed. This improves esbuild's alignment with the JavaScript specification. Some examples of cases that were previously allowed but that are now no longer allowed:
v0.11.12
Compare Source
Fix a bug where
-0
and0
were collapsed to the same value (#1159)Previously esbuild would collapse
Object.is(x ? 0 : -0, -0)
intoObject.is((x, 0), -0)
during minification, which is incorrect. The IEEE floating-point value-0
is a different bit pattern than0
and while they both compare equal, the difference is detectable in a few scenarios such as when usingObject.is()
. The minification transformation now checks for-0
vs.0
and no longer has this bug. This fix was contributed by @rtsao.Match the TypeScript compiler's output in a strange edge case (#1158)
With this release, esbuild's TypeScript-to-JavaScript transform will no longer omit the namespace in this case:
This was previously omitted because TypeScript omits empty namespaces, and the namespace was considered empty because the
export declare function
statement isn't "real":The TypeScript compiler compiles the above code into the following:
Notice how
Something.Print
is never called, and what appears to be a reference to thePrint
symbol on the namespaceSomething
is actually a reference to the global variablePrint
. I can only assume this is a bug in TypeScript, but it's important to replicate this behavior inside esbuild for TypeScript compatibility.The TypeScript-to-JavaScript transform in esbuild has been updated
Configuration
📅 Schedule: "before 3am on Monday" (UTC).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻️ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by WhiteSource Renovate. View repository job log here.