-
Fix bundling when parent directory is inaccessible (#938)
Previously bundling with esbuild when a parent directory is inaccessible did not work because esbuild would try to read the directory to search for a
node_modules
folder and would then fail the build when that failed. In practice this caused issues in certain Linux environments where a directory close to the root directory was inaccessible (e.g. on Android). With this release, esbuild will treat inaccessible directories as empty to allow for thenode_modules
search to continue past the inaccessible directory and into its parent directory. This means it should now be possible to bundle with esbuild in these situations. -
Avoid allocations in JavaScript API stdout processing (#941)
This release improves the efficiency of the JavaScript API. The API runs the binary esbuild executable in a child process and then communicates with it over stdin/stdout. Previously the stdout buffer containing the remaining partial message was copied after each batch of messages due to a bug. This was unintentional and unnecessary, and has been removed. Now this part of the code no longer involves any allocations. This fix was contributed by @jridgewell.
-
Support conditional
@import
syntax when not bundling (#953)Previously conditional CSS imports such as
@import "print.css" print;
was not supported at all and was considered a syntax error. With this release, it is now supported in all cases except when bundling an internal import. Support for bundling internal CSS imports is planned but will happen in a later release. -
Always lower object spread and rest when targeting V8 (#951)
This release causes object spread (e.g.
a = {...b}
) and object rest (e.g.{...a} = b
) to always be lowered to a manual implementation instead of using native syntax when the--target=
parameter includes a V8-based JavaScript runtime such aschrome
,edge
, ornode
. It turns out this feature is implemented inefficiently in V8 and copying properties over to a new object is around a 2x performance improvement. In addition, doing this manually instead of using the native implementation generates a lot less work for the garbage collector. You can see V8 bug 11536 for details. If the V8 performance bug is eventually fixed, the translation of this syntax will be disabled again for V8-based targets containing the bug fix. -
Fix object rest return value (#956)
This release fixes a bug where the value of an object rest assignment was incorrect if the object rest assignment was lowered:
// This code was affected let x, y console.log({x, ...y} = {x: 1, y: 2})
Previously this code would incorrectly print
{y: 2}
(the value assigned toy
) when the object rest expression was lowered (i.e. with--target=es2017
or below). Now this code will correctly print{x: 1, y: 2}
instead. This bug did not affect code that did not rely on the return value of the assignment expression, such as this code:// This code was not affected let x, y ({x, ...y} = {x: 1, y: 2})
-
Basic support for CSS page margin rules (#955)
There are 16 different special at-rules that can be nested inside the
@page
rule. They are defined in this specification. Previously esbuild treated these as unknown rules, but with this release esbuild will now treat these as known rules. The only real difference in behavior is that esbuild will no longer warn about these rules being unknown. -
Add export name annotations to CommonJS output for node
When you import a CommonJS file using an ESM
import
statement in node, thedefault
import is the value ofmodule.exports
in the CommonJS file. In addition, node attempts to generate named exports for properties of themodule.exports
object.Except that node doesn't actually ever look at the properties of that object to determine the export names. Instead it parses the CommonJS file and scans the AST for certain syntax patterns. A full list of supported patterns can be found in the documentation for the
cjs-module-lexer
package. This library doesn't currently support the syntax patterns used by esbuild.While esbuild could adapt its syntax to these patterns, the patterns are less compact than the ones used by esbuild and doing this would lead to code bloat. Supporting two separate ways of generating export getters would also complicate esbuild's internal implementation, which is undesirable.
Another alternative could be to update the implementation of
cjs-module-lexer
to support the specific patterns used by esbuild. This is also undesirable because this pattern detection would break when minification is enabled, this would tightly couple esbuild's output format with node and prevent esbuild from changing it, and it wouldn't work for existing and previous versions of node that still have the old version of this library.Instead, esbuild will now add additional code to "annotate" ESM files that have been converted to CommonJS when esbuild's platform has been set to
node
. The annotation is dead code but is still detected by thecjs-module-lexer
library. If the original ESM file has the exportsfoo
andbar
, the additional annotation code will look like this:0 && (module.exports = {foo, bar});
This allows you to use named imports with an ESM
import
statement in node (previously you could only use thedefault
import):import { foo, bar } from './file-built-by-esbuild.cjs'