📦 Update dependency esbuild to v0.11.16 - autoclosed#34035
Closed
renovate-bot wants to merge 1 commit intoampproject:mainfrom
Closed
📦 Update dependency esbuild to v0.11.16 - autoclosed#34035renovate-bot wants to merge 1 commit intoampproject:mainfrom
renovate-bot wants to merge 1 commit intoampproject:mainfrom
Conversation
1 task
fe9f96a to
2f95ec5
Compare
d50e5ce to
091da9d
Compare
Contributor
|
I suspect the latest transformation error in |
0840c1c to
cfa23f3
Compare
cfa23f3 to
8f7c66c
Compare
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.9.7->0.11.16How to resolve breaking changes
This PR may introduce breaking changes that require manual intervention. In such cases, you will need to check out this branch, fix the cause of the breakage, and commit the fix to ensure a green CI build. To check out and update this PR, follow the steps below:
Release Notes
evanw/esbuild
v0.11.16Compare Source
Fix TypeScript
enumedge case (#1198)In TypeScript, you can reference the inner closure variable in an
enumwithin the inner closure by name:The TypeScript compiler generates the following code for this case:
However, TypeScript also lets you declare an
enumvalue 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
enumvalue and the inner closure variable with the same name. With this release, the shadowing is now handled correctly.Parse the
@-moz-documentCSS 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-documentCSS 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 = 2was incorrectly eagerly validated as a default argument. With this release, the reporting of the default argument error when targetinges5is 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
browserfield (#1209)This release includes some changes to how the
browserfield inpackage.jsonis 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 ofbrowserfield test cases and esbuild's behavior should now be consistent with other bundlers again.Avoid placing a
super()call inside areturnstatement (#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 thereturnstatement 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 insidereturnstatements (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
onEndand watch mode (#1186)This release fixes a bug where
onEndplugin callbacks only worked with watch mode when anonRebuildwatch mode callback was present. NowonEndcallbacks should fire even if there is noonRebuildcallback.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 missingasynckeyword 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.15Compare Source
Provide options for how to handle legal comments (#919)
A "legal comment" is considered to be any comment that contains
@licenseor@preserveor 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 andlegalCommentsin 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.txtfile and link to them with a commentexternal: Move all statement-level legal comments to a.LEGAL.txtfile but to not link to themThe default behavior is
eofwhen bundling andinlineotherwise.Add
onStartandonEndcallbacks to the plugin APIPlugins can now register callbacks to run when a build is started and ended:
One benefit of
onStartandonEndis 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
onStartcallback for initialization since it can be run multiple times. If you want to initialize something, just put your plugin initialization code directly inside thesetupfunction instead.The
onStartcallback can beasyncand can return a promise. However, the build does not wait for the promise to be resolved before starting, so a slowonStartcallback will not necessarily slow down the build. AllonStartcallbacks are also run concurrently, not consecutively. The returned promise is purely for error reporting, and matters when theonStartcallback needs to do an asynchronous operation that may fail. If your plugin needs to wait for an asynchronous task inonStartto complete before anyonResolveoronLoadcallbacks are run, you will need to have youronResolveoronLoadcallbacks block on that task fromonStart.Note that
onStartcallbacks do not have the ability to mutatebuild.initialOptions. The initial options can only be modified within thesetupfunction and are consumed once thesetupfunction returns. All rebuilds use the same initial options so the initial options are never re-consumed, and modifications tobuild.initialOptionsthat are done withinonStartare ignored.build.onEnd()All
onEndcallbacks 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 = trueand the build graph will be returned as themetafileproperty on the build result object.v0.11.14Compare 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
sideEffectsbehavior from Webpack (#1184)This release adds support for the implicit
**/prefix that must be added to paths in thesideEffectsarray inpackage.jsonif the path does not contain/. Another way of saying this is ifpackage.jsoncontains asideEffectsarray 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.13Compare 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-overwriteflag (#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.bwill 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.12Compare Source
Fix a bug where
-0and0were 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-0is a different bit pattern than0and while they both compare equal, the difference is detectable in a few scenarios such as when usingObject.is(). The minification transformation now checks for-0vs.0and 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 functionstatement isn't "real":The TypeScript compiler compiles the above code into the following:
Notice how
Something.Printis never called, and what appears to be a reference to thePrintsymbol on the namespaceSomethingis 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 to match the TypeScript compiler's output in both of these cases.
Separate the
debuglog level intodebugandverboseYou can now use
--log-level=debugto get some additional information that might indicate some problems with your build, but that has a high-enough false-positive rate that it isn't appropriate for warnings, which are on by default. Enabling thedebuglog level no longer generates a torrent of debug information like it did in the past; that behavior is now reserved for theverboselog level instead.v0.11.11Compare Source
Initial support for Deno (#936)
You can now use esbuild in the Deno JavaScript environment via esbuild's official Deno package. Using it looks something like this:
It has basically the same API as esbuild's npm package with one addition: you need to call
stop()when you're done because unlike node, Deno doesn't provide the necessary APIs to allow Deno to exit while esbuild's internal child process is still running.Remove warnings about non-bundled use of
requireandimport(#1153, #1142, #1132, #1045, #812, #661, #574, #512, #495, #480, #453, #410, #80)Previously esbuild had warnings when bundling about uses of
requireandimportthat are not of the formrequire(<string literal>)orimport(<string literal>). These warnings existed because the bundling process must be able to statically-analyze all dynamic imports to determine which files must be included. Here are some real-world examples of cases that esbuild doesn't statically analyze:From
mongoose:From
moment:From
logform:All of these dynamic imports will not be bundled (i.e. they will be left as-is) and will crash at run-time if they are evaluated. Some of these crashes are ok since the code paths may have error handling or the code paths may never be used. Other crashes are not ok because the crash will actually be hit.
The warning from esbuild existed to let you know that esbuild is aware that it's generating a potentially broken bundle. If you discover that your bundle is broken, it's nice to have a warning from esbuild to point out where the problem is. And it was just a warning so the build process still finishes and successfully generates output files. If you didn't want to see the warning, it was easy to turn it off via
--log-level=error.However, there have been quite a few complaints about this warning. Some people seem to not understand the difference between a warning and an error, and think the build has failed even though output files were generated. Other people do not want to see the warning but also do not want to enable
--log-level=error.This release removes this warning for both
requireandimport. Now when you try to bundle code with esbuild that contains dynamic imports not of the formrequire(<string literal>)orimport(<string literal>), esbuild will just silently generate a potentially broken bundle. This may affect people coming from other bundlers that support certain forms of dynamic imports that are not compatible with esbuild such as the Webpack-specific dynamicimport()with pattern matching.v0.11.10Compare Source
Provide more information about
exportsmap import failures if possible (#1143)Node has a new feature where you can add an
exportsmap to yourpackage.jsonfile to control how external import paths map to the files in your package. You can change which paths map to which files as well as make it impossible to import certain files (i.e. the files are private).If path resolution fails due to an
exportsmap and the failure is not related to import conditions, esbuild's current error message for this just says that the import isn't possible:This error message matches the error that node itself throws. However, the message could be improved in the case where someone is trying to import a file using its file system path and that path is actually exported by the package, just under a different export path. This case comes up a lot when using TypeScript because the TypeScript compiler (and therefore the Visual Studio Code IDE) still doesn't support package
exports.With this release, esbuild will now do a reverse lookup of the file system path using the
exportsmap to determine what the correct import path should be:Hopefully this should enable people encountering this issue to fix the problem themselves.
v0.11.9Compare Source
Fix escaping of non-BMP characters in property names (#977)
Property names in object literals do not have to be quoted if the property is a valid JavaScript identifier. This is defined as starting with a character in the
ID_StartUnicode category and ending with zero or more characters in theID_ContinueUnicode category. However, esbuild had a bug where non-BMP characters (i.e. characters encoded using two UTF-16 code units instead of one) were always checked againstID_Continueinstead ofID_Startbecause they included a code unit that wasn't at the start. This could result in invalid JavaScript being generated when using--charset=utf8becauseID_Continueis a superset ofID_Startand contains some characters that are not valid at the start of an identifier. This bug has been fixed.Be maximally liberal in the interpretation of the
browserfield (#740)The
browserfield inpackage.jsonis an informal convention followed by browser-specific bundlers that allows package authors to substitute certain node-specific import paths with alternative browser-specific import paths. It doesn't have a rigorous specification and the canonical description of the feature doesn't include any tests. As a result, each bundler implements this feature differently. I have tried to create a survey of how different bundlers interpret thebrowserfield and the results are very inconsistent.This release attempts to change esbuild to support the union of the behavior of all other bundlers. That way if people have the
browserfield working with some other bundler and they switch to esbuild, thebrowserfield shouldn't ever suddenly stop working. This seemed like the most principled approach to take in this situation.The drawback of this approach is that it means the
browserfield may start working when switching to esbuild when it was previously not working. This could cause bugs, but I consider this to be a problem with the package (i.e. not using a more well-supported form of thebrowserfield), not a problem with esbuild itself.v0.11.8Compare Source
Fix hash calculation for code splitting and dynamic imports (#1076)
The hash included in the file name of each output file is intended to change if and only if anything relevant to the content of that output file changes. It includes:
The contents of the file with the paths of other output files omitted
The output path of the file the final hash omitted
Some information about the input files involved in that output file
The contents of the associated source map, if there is one
All of the information above for all transitive dependencies found by following
importstatementsHowever, this didn't include dynamic
import()expressions due to an oversight. With this release, dynamicimport()expressions are now also counted as transitive dependencies. This fixes an issue where the content of an output file could change without its hash also changing. As a side effect of this change, dynamic imports inside output files of other output files are now listed in the metadata file if themetafilesetting is enabled.Refactor the internal module graph representation
This release changes a large amount of code relating to esbuild's internal module graph. The changes are mostly organizational and help consolidate most of the logic around maintaining various module graph invariants into a separate file where it's easier to audit. The Go language doesn't have great abstraction capabilities (e.g. no zero-cost iterators) so the enforcement of this new abstraction is unfortunately done by convention instead of by the compiler, and there is currently still some code that bypasses the abstraction. But it's better than it was before.
Another relevant change was moving a number of special cases that happened during the tree shaking traversal into the graph itself instead. Previously there were quite a few implicit dependency rules that were checked in specific places, which was hard to follow. Encoding these special case constraints into the graph itself makes the problem easier to reason about and should hopefully make the code more regular and robust.
Finally, this set of changes brings back full support for the
sideEffectsannotation inpackage.json. It was previously disabled when code splitting was active as a temporary measure due to the discovery of some bugs in that scenario. But I believe these bugs have been resolved now that tree shaking and code splitting are done in separate passes (see the previous release for more information).v0.11.7Compare Source
Fix incorrect chunk reference with code splitting, css, and dynamic imports (#1125)
This release fixes a bug where when you use code splitting, CSS imports in JS, and dynamic imports all combined, the dynamic import incorrectly references the sibling CSS chunk for the dynamic import instead of the primary JS chunk. In this scenario the entry point file corresponds to two different output chunks (one for CSS and one for JS) and the wrong chunk was being picked. This bug has been fixed.
Split apart tree shaking and code splitting (#1123)
The original code splitting algorithm allowed for files to be split apart and for different parts of the same file to end up in different chunks based on which entry points needed which parts. This was done at the same time as tree shaking by essentially performing tree shaking multiple times, once per entry point, and tracking which entry points each file part is live in. Each file part that is live in at least one entry point was then assigned to a code splitting chunk with all of the other code that is live in the same set of entry points. This ensures that entry points only import code that they will use (i.e. no code will be downloaded by an entry point that is guaranteed to not be used).
This file-splitting feature has been removed because it doesn't work well with the recently-added top-level await JavaScript syntax, which has complex evaluation order rules that operate at file boundaries. File parts now have a single boolean flag for whether they are live or not instead of a set of flags that track which entry points that part is reachable from (reachability is still tracked at the file level).
However, this change appears to have introduced some subtly incorrect behavior with code splitting because there is now an implicit dependency in the import graph between adjacent parts within the same file even if the two parts are unrelated and don't reference each other. This is due to the fact each entry point that references one part pulls in the file (but not the whole file, only the parts that are live in at least one entry point). So liveness must be fully computed first before code splitting is computed.
This release splits apart tree shaking and code splitting into two separate passes, which fixes certain cases where two generated code splitting chunks ended up each importing symbols from the other and causing a cycle. There should hopefully no longer be cycles in generated code splitting chunks.
Make
thiswork in static class fields in TypeScript filesCurrently
thisis mis-compiled in static fields in TypeScript files if theuseDefineForClassFieldssetting intsconfig.jsonisfalse(the default value):This is currently compiled into the code below, which is incorrect because it changes the value of
this(it's supposed to refer toFoo):This was an intentionally unhandled case because the TypeScript compiler doesn't handle this either (esbuild's currently incorrect output matches the output from the TypeScript compiler, which is also currently incorrect). However, the TypeScript compiler might fix their output at some point in which case esbuild's behavior would become problematic.
So this release now generates the correct output:
Presumably the TypeScript compiler will be fixed to also generate something like this in the future. If you're wondering why esbuild generates the extra
_Foovariable, it's defensive code to handle the possibility of the class being reassigned, since class declarations are not constants:We can't just move the initializer containing
Foo.foooutside of the class body because in JavaScript, the class name is shadowed inside the class body by a special hidden constant that is equal to the class object. Even if the class is reassigned later, references to that shadowing symbol within the class body should still refer to the original class object.Various fixes for private class members (#1131)
This release fixes multiple issues with esbuild's handling of the
#privatesyntax. Previously there could be scenarios where references tothis.#privatecould be moved outside of the class body, which would cause them to become invalid (since the#privatename is only available within the class body). One such case is when TypeScript'suseDefineForClassFieldssetting has the valuefalse(which is the default value), which causes class field initializers to be replaced with assignment expressions to avoid using "define" semantics:Previously this was turned into the following code, which is incorrect because
Foo.#foowas moved outside of the class body:This is now handled by converting the private field syntax into normal JavaScript that emulates it with a
WeakMapinstead.This conversion is fairly conservative to make sure certain edge cases are covered, so this release may unfortunately convert more private fields than previous releases, even when the target is
esnext. It should be possible to improve this transformation in future releases so that this happens less often while still preserving correctness.v0.11.6Compare Source
Fix an incorrect minification transformation (#1121)
This release removes an incorrect substitution rule in esbuild's peephole optimizer, which is run when minification is enabled. The incorrect rule transformed
if(a && falsy)intoif(a, falsy)which is equivalent iffalsyhas no side effects (such as the literalfalse). However, the rule didn't check that the expression is side-effect free first which could result in miscompiled code. I have removed the rule instead of modifying it to check for the lack of side effects first because while the code is slightly smaller, it may also be more expensive at run-time which is undesirable. The size savings are also very insignificant.Change how
NODE_PATHworks to match node (#1117)Node searches for packages in nearby
node_modulesdirectories, but it also allows you to inject extra directories to search for packages in using theNODE_PATHenvironment variable. This is supported when using esbuild's CLI as well as via thenodePathsoption when using esbuild's API.Node's module resolution algorithm is well-documented, and esbuild's path resolution is designed to follow it. The full algorithm is here: https://nodejs.org/api/modules.html#modules_all_together. However, it appears that the documented algorithm is incorrect with regard to
NODE_PATH. The documentation saysNODE_PATHdirectories should take precedence overnode_modulesdirectories, and so that's how esbuild worked. However, in practice node actually does it the other way around.Starting with this release, esbuild will now allow
node_modulesdirectories to take precedence overNODE_PATHdirectories. This is a deviation from the published algorithm.Provide a better error message for incorrectly-quoted JSX attributes (#959, #1115)
People sometimes try to use the output of
JSON.stringify()as a JSX attribute when automatically-generating JSX code. Doing so is incorrect because JSX strings work like XML instead of like JS (since JSX is XML-in-JS). Specifically, using a backslash before a quote does not cause it to be escaped:It's not just esbuild; Babel and TypeScript also treat this as a syntax error. All of these JSX parsers are just following the JSX specification. This has come up twice now so it could be worth having a dedicated error message. Previously esbuild had a generic syntax error like this:
Now esbuild will provide more information if it detects this case:
v0.11.5Compare Source
Add support for the
overridekeyword in TypeScript 4.3 (#1105)The latest version of TypeScript (now in beta) adds a new keyword called
overridethat can be used on class members. You can read more about this feature in Microsoft's blog post about TypeScript 4.3. It looks like this:With this release, esbuild will now ignore the
overridekeyword when parsing TypeScript code instead of treating this keyword as a syntax error, which means esbuild can now support TypeScript 4.3 syntax. This change was contributed by @g-plane.Allow
asyncpluginsetupfunctionsWith this release, you can now return a promise from your plugin's
setupfunction to delay the start of the build:This is useful if your plugin needs to do something asynchronous before the build starts. For example, you may need some asynchronous information before modifying the
initialOptionsobject, which must be done before the build starts for the modifications to take effect.Add some optimizations around hashing
This release contains two optimizations to the hashes used in output file names:
Hash generation now happens in parallel with other work, and other work only blocks on the hash computation if the hash ends up being needed (which is only if
[hash]is included in--entry-names=, and potentially--chunk-names=if it's relevant). This is a performance improvement because--entry-names=does not include[hash]in the default case, so bundling time no longer always includes hashing time.The hashing algorithm has been changed from SHA1 to xxHash (specifically this Go implementation) which means the hashing step is around 6x faster than before. Thanks to @Jarred-Sumner for the suggestion.
Disable tree shaking annotations when code splitting is active (#1070, #1081)
Support for Webpack's
"sideEffects": falseannotation inpackage.jsonis now disabled when code splitting is enabled and there is more than one entry point. This avoids a bug that could cause generated chunks to reference each other in some cases. Now all chunks generated by code splitting should be acyclic.v0.11.4Compare Source
Avoid name collisions with TypeScript helper functions (#1102)
Helper functions are sometimes used when transforming newer JavaScript syntax for older browsers. For example,
let {x, ...y} = {z}is transformed intolet _a = {z}, {x} = _a, y = __rest(_a, ["x"])which uses the__resthelper function. Many of esbuild's transforms were modeled after the transforms in the TypeScript compiler, so many of the helper functions use the same names as TypeScript's helper functions.However, the TypeScript compiler doesn't avoid name collisions with existing identifiers in the transformed code. This means that post-processing esbuild's output with the TypeScript compiler (e.g. for lowering ES6 to ES5) will cause issues since TypeScript will fail to call its own helper functions: microsoft/TypeScript#43296. There is also a problem where TypeScript's
tsliblibrary overwrites globals with these names, which can overwrite esbuild's helper functions if code bundled with esbuild is run in the global scope.To avoid these problems, esbuild will now use different names for its helper functions.
Fix a chunk hashing issue (#1099)
Previously the chunk hashing algorithm skipped hashing entry point chunks when the
--entry-names=setting doesn't contain[hash], since the hash wasn't used in the file name. However, this is no longer correct with the change in version 0.11.0 that made dynamic entry point chunks use--chunk-names=instead of--entry-names=since--chunk-names=can still contain[hash].With this release, chunk contents will now always be hashed regardless of the chunk type. This makes esbuild somewhat slower than before in the common case, but it fixes this correctness issue.
v0.11.3Compare Source
Auto-define
process.env.NODE_ENVwhen platform is set tobrowserAll code in the React world has the requirement that the specific expression
process.env.NODE_ENVmust be replaced with a string at compile-time or your code will immediately crash at run-time. This is a common stumbling point for people when they start using esbuild with React. Previously bundling code with esbuild containingprocess.env.NODE_ENVwithout defining a string replacement first was a warning that warned you about the lack of a define.With this release esbuild will now attempt to define
process.env.NODE_ENVautomatically instead of warning about it. This will be implicitly defined to"production"if minification is enabled and"development"otherwise. This automatic behavior only happens when the platform isbrowser, sinceprocessis not a valid browser API and will never exist in the browser. This is also only done if there are no existing defines forprocess,process.env, orprocess.env.NODE_ENVso you can override the automatic value if necessary. If you need to disable this behavior, you can use theneutralplatform instead of thebrowserplatform.Retain side-effect free intermediate re-exporting files (#1088)
This fixes a subtle bug with esbuild's support for Webpack's
"sideEffects": falseannotation inpackage.jsonwhen combined with re-export statements. A re-export is when you import something from one file and then export it again. You can re-export something withexport * fromorexport {foo} fromorimport {foo} fromfollowed byexport {foo}.The bug was that files which only contain re-exports and that are marked as being side-effect free were not being included in the bundle if you import one of the re-exported symbols. This is because esbuild's implementation of re-export linking caused the original importing file to "short circuit" the re-export and just import straight from the file containing the final symbol, skipping the file containing the re-export entirely.
This was normally not observable since the intermediate file consisted entirely of re-exports, which have no side effects. However, a recent change to allow ESM files to be lazily-initialized relies on all intermediate files being included in the bundle to trigger the initialization of the lazy evaluation wrappers. So the behavior of skipping over re-export files is now causing the imported symbols to not be initialized if the re-exported file is marked as lazily-evaluated.
The fix is to track all re-exports in the import chain from the original file to the file containing the final symbol and then retain all of those statements if the import ends up being used.
Add a very verbose
debuglog levelThis log level is an experiment. Enabling it logs a lot of information (currently only about path resolution). The idea is that if you are having an obscure issue, the debug log level might contain some useful information. Unlike normal logs which are meant to mainly provide actionable information, these debug logs are intentionally mostly noise and are designed to be searched through instead.
Here is an example of debug-level log output:
v0.11.2Compare Source
Fix missing symbol dependency for wrapped ESM files (#1086)
An internal graph node was missing an edge, which could result in generating code that crashes at run-time when code splitting is enabled. Specifically a part containing an import statement must depend on the imported file's wrapper symbol if the imported file is wrapped, regardless of whether it's a wrapped CommonJS or ESM file. Previously this was only the case for CommonJS files but not for ESM files, which is incorrect. This bug has been fixed.
Fix an edge case with entry points and top-level await
If an entry point uses
import()on itself, it currently has to be wrapped sinceimport()expressions call the wrapper for the imported file. This means the another call to the wrapper must be inserted at the bottom of the entry point file to start the lazy evaluation of the entry point code (otherwise nothing will be evaluated, since the entry point is wrapped). However, if this entry point then contains a top-level await that means the wrapper isasyncand must be passed toawaitto catch and forward any exceptions thrown during the evaluation of the entry point code. Thisawaitwas previously missing in this specific case due to a bug, but theawaitshould now be added in this release.v0.11.1Compare Source
Fix TypeScript
enumedge case (#1198)In TypeScript, you can reference the inner closure variable in an
enumwithin the inner closure by name:The TypeScript compiler generates the following code for this case:
However, TypeScript also lets you declare an
enumvalue 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
enumvalue and the inner closure variable with the same name. With this release, the shadowing is now handled correctly.Parse the
@-moz-documentCSS 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-documentCSS 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 speculatConfiguration
📅 Schedule: "after 12am every weekday" in timezone America/Los_Angeles.
🚦 Automerge: Enabled.
♻️ 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.