evanw/esbuild
### [`v0.13.12`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01312)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.11...v0.13.12)
- Implement initial support for simplifying `calc()` expressions in CSS ([#1607](https://togithub.com/evanw/esbuild/issues/1607))
This release includes basic simplification of `calc()` expressions in CSS when minification is enabled. The approach mainly follows the official CSS specification, which means it should behave the way browsers behave: https://www.w3.org/TR/css-values-4/#calc-func. This is a basic implementation so there are probably some `calc()` expressions that can be reduced by other tools but not by esbuild. This release mainly focuses on setting up the parsing infrastructure for `calc()` expressions to make it straightforward to implement additional simplifications in the future. Here's an example of this new functionality:
```css
/* Input CSS */
div {
width: calc(60px * 4 - 5px * 2);
height: calc(100% / 4);
}
/* Output CSS (with --minify-syntax) */
div {
width: 230px;
height: 25%;
}
```
Expressions that can't be fully simplified will still be partially simplified into a reduced `calc()` expression:
```css
/* Input CSS */
div {
width: calc(100% / 5 - 2 * 1em - 2 * 1px);
}
/* Output CSS (with --minify-syntax) */
div {
width: calc(20% - 2em - 2px);
}
```
Note that this transformation doesn't attempt to modify any expression containing a `var()` CSS variable reference. These variable references can contain any number of tokens so it's not safe to move forward with a simplification assuming that `var()` is a single token. For example, `calc(2px * var(--x) * 3)` is not transformed into `calc(6px * var(--x))` in case `var(--x)` contains something like `4 + 5px` (`calc(2px * 4 + 5px * 3)` evaluates to `23px` while `calc(6px * 4 + 5px)` evaluates to `29px`).
- Fix a crash with a legal comment followed by an import ([#1730](https://togithub.com/evanw/esbuild/issues/1730))
Version 0.13.10 introduced parsing for CSS legal comments but caused a regression in the code that checks whether there are any rules that come before `@import`. This is not desired because browsers ignore `@import` rules after other non-`@import` rules, so esbuild warns you when you do this. However, legal comments are modeled as rules in esbuild's internal AST even though they aren't actual CSS rules, and the code that performs this check wasn't updated. This release fixes the crash.
### [`v0.13.11`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01311)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.10...v0.13.11)
- Implement class static blocks ([#1558](https://togithub.com/evanw/esbuild/issues/1558))
This release adds support for a new upcoming JavaScript feature called [class static blocks](https://togithub.com/tc39/proposal-class-static-block) that lets you evaluate code inside of a class body. It looks like this:
```js
class Foo {
static {
this.foo = 123
}
}
```
This can be useful when you want to use `try`/`catch` or access private `#name` fields during class initialization. Doing that without this feature is quite hacky and basically involves creating temporary static fields containing immediately-invoked functions and then deleting the fields after class initialization. Static blocks are much more ergonomic and avoid performance loss due to `delete` changing the object shape.
Static blocks are transformed for older browsers by moving the static block outside of the class body and into an immediately invoked arrow function after the class definition:
```js
// The transformed version of the example code above
const _Foo = class {
};
let Foo = _Foo;
(() => {
_Foo.foo = 123;
})();
```
In case you're wondering, the additional `let` variable is to guard against the potential reassignment of `Foo` during evaluation such as what happens below. The value of `this` must be bound to the original class, not to the current value of `Foo`:
```js
let bar
class Foo {
static {
bar = () => this
}
}
Foo = null
console.log(bar()) // This should not be "null"
```
- Fix issues with `super` property accesses
Code containing `super` property accesses may need to be transformed even when they are supported. For example, in ES6 `async` methods are unsupported while `super` properties are supported. An `async` method containing `super` property accesses requires those uses of `super` to be transformed (the `async` function is transformed into a nested generator function and the `super` keyword cannot be used inside nested functions).
Previously esbuild transformed `super` property accesses into a function call that returned the corresponding property. However, this was incorrect for uses of `super` that write to the inherited setter since a function call is not a valid assignment target. This release fixes writing to a `super` property:
```js
// Original code
class Base {
set foo(x) { console.log('set foo to', x) }
}
class Derived extends Base {
async bar() { super.foo = 123 }
}
new Derived().bar()
// Old output with --target=es6 (contains a syntax error)
class Base {
set foo(x) {
console.log("set foo to", x);
}
}
class Derived extends Base {
bar() {
var __super = (key) => super[key];
return __async(this, null, function* () {
__super("foo") = 123;
});
}
}
new Derived().bar();
// New output with --target=es6 (works correctly)
class Base {
set foo(x) {
console.log("set foo to", x);
}
}
class Derived extends Base {
bar() {
var __superSet = (key, value) => super[key] = value;
return __async(this, null, function* () {
__superSet("foo", 123);
});
}
}
new Derived().bar();
```
All known edge cases for assignment to a `super` property should now be covered including destructuring assignment and using the unary assignment operators with BigInts.
In addition, this release also fixes a bug where a `static` class field containing a `super` property access was not transformed when it was moved outside of the class body, which can happen when `static` class fields aren't supported.
```js
// Original code
class Base {
static get foo() {
return 123
}
}
class Derived extends Base {
static bar = super.foo
}
// Old output with --target=es6 (contains a syntax error)
class Base {
static get foo() {
return 123;
}
}
class Derived extends Base {
}
__publicField(Derived, "bar", super.foo);
// New output with --target=es6 (works correctly)
class Base {
static get foo() {
return 123;
}
}
const _Derived = class extends Base {
};
let Derived = _Derived;
__publicField(Derived, "bar", __superStaticGet(_Derived, "foo"));
```
All known edge cases for `super` inside `static` class fields should be handled including accessing `super` after prototype reassignment of the enclosing class object.
### [`v0.13.10`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01310)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.9...v0.13.10)
- Implement legal comment preservation for CSS ([#1539](https://togithub.com/evanw/esbuild/issues/1539))
This release adds support for legal comments in CSS the same way they are already supported for JS. A legal comment is one that starts with `/*!` or that contains the text `@license` or `@preserve`. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code. The specific behavior is controlled via `--legal-comments=` in the CLI and `legalComments` in the JS API, which can be set to any of the following options:
- `none`: Do not preserve any legal comments
- `inline`: Preserve all rule-level legal comments
- `eof`: Move all rule-level legal comments to the end of the file
- `linked`: Move all rule-level legal comments to a `.LEGAL.txt` file and link to them with a comment
- `external`: Move all rule-level legal comments to a `.LEGAL.txt` file but to not link to them
The default behavior is `eof` when bundling and `inline` otherwise.
- Allow uppercase `es*` targets ([#1717](https://togithub.com/evanw/esbuild/issues/1717))
With this release, you can now use target names such as `ESNext` instead of `esnext` as the target name in the CLI and JS API. This is important because people don't want to have to call `.toLowerCase()` on target strings from TypeScript's `tsconfig.json` file before passing it to esbuild (TypeScript uses case-agnostic target names).
This feature was contributed by [@timse](https://togithub.com/timse).
- Update to Unicode 14.0.0
The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 13.0.0 to the newly release Unicode version 14.0.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode14.0.0/#Summary for more information about the changes.
### [`v0.13.9`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0139)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.8...v0.13.9)
- Add support for `imports` in `package.json` ([#1691](https://togithub.com/evanw/esbuild/issues/1691))
This release adds basic support for the `imports` field in `package.json`. It behaves similarly to the `exports` field but only applies to import paths that start with `#`. The `imports` field provides a way for a package to remap its own internal imports for itself, while the `exports` field provides a way for a package to remap its external exports for other packages. This is useful because the `imports` field respects the currently-configured conditions which means that the import mapping can change at run-time. For example:
$ cat entry.mjs
import '#example'
$ cat package.json
{
"imports": {
"#example": {
"foo": "./example.foo.mjs",
"default": "./example.mjs"
}
}
}
$ cat example.foo.mjs
console.log('foo is enabled')
$ cat example.mjs
console.log('foo is disabled')
$ node entry.mjs
foo is disabled
$ node --conditions=foo entry.mjs
foo is enabled
Now that esbuild supports this feature too, import paths starting with `#` and any provided conditions will be respected when bundling:
$ esbuild --bundle entry.mjs | node
foo is disabled
$ esbuild --conditions=foo --bundle entry.mjs | node
foo is enabled
- Fix using `npm rebuild` with the `esbuild` package ([#1703](https://togithub.com/evanw/esbuild/issues/1703))
Version 0.13.4 accidentally introduced a regression in the install script where running `npm rebuild` multiple times could fail after the second time. The install script creates a copy of the binary executable using [`link`](https://man7.org/linux/man-pages/man2/link.2.html) followed by [`rename`](https://www.man7.org/linux/man-pages/man2/rename.2.html). Using `link` creates a hard link which saves space on the file system, and `rename` is used for safety since it atomically replaces the destination.
However, the `rename` syscall has an edge case where it silently fails if the source and destination are both the same link. This meant that the install script would fail after being run twice in a row. With this release, the install script now deletes the source after calling `rename` in case it has silently failed, so this issue should now be fixed. It should now be safe to use `npm rebuild` with the `esbuild` package.
- Fix invalid CSS minification of `border-radius` ([#1702](https://togithub.com/evanw/esbuild/issues/1702))
CSS minification does collapsing of `border-radius` related properties. For example:
```css
/* Original CSS */
div {
border-radius: 1px;
border-top-left-radius: 5px;
}
/* Minified CSS */
div{border-radius:5px 1px 1px}
```
However, this only works for numeric tokens, not identifiers. For example:
```css
/* Original CSS */
div {
border-radius: 1px;
border-top-left-radius: inherit;
}
/* Minified CSS */
div{border-radius:1px;border-top-left-radius:inherit}
```
Transforming this to `div{border-radius:inherit 1px 1px}`, as was done in previous releases of esbuild, is an invalid transformation and results in incorrect CSS. This release of esbuild fixes this CSS transformation bug.
### [`v0.13.8`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0138)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.7...v0.13.8)
- Fix `super` inside arrow function inside lowered `async` function ([#1425](https://togithub.com/evanw/esbuild/issues/1425))
When an `async` function is transformed into a regular function for target environments that don't support `async` such as `--target=es6`, references to `super` inside that function must be transformed too since the `async`-to-regular function transformation moves the function body into a nested function, so the `super` references are no longer syntactically valid. However, this transform didn't handle an edge case and `super` references inside of an arrow function were overlooked. This release fixes this bug:
```js
// Original code
class Foo extends Bar {
async foo() {
return () => super.foo()
}
}
// Old output (with --target=es6)
class Foo extends Bar {
foo() {
return __async(this, null, function* () {
return () => super.foo();
});
}
}
// New output (with --target=es6)
class Foo extends Bar {
foo() {
var __super = (key) => super[key];
return __async(this, null, function* () {
return () => __super("foo").call(this);
});
}
}
```
- Remove the implicit `/` after `[dir]` in entry names ([#1661](https://togithub.com/evanw/esbuild/issues/1661))
The "entry names" feature lets you customize the way output file names are generated. The `[dir]` and `[name]` placeholders are filled in with the directory name and file name of the corresponding entry point file, respectively.
Previously `--entry-names=[dir]/[name]` and `--entry-names=[dir][name]` behaved the same because the value used for `[dir]` always had an implicit trailing slash, since it represents a directory. However, some people want to be able to remove the file name with `--entry-names=[dir]` and the implicit trailing slash gets in the way.
With this release, you can now use the `[dir]` placeholder without an implicit trailing slash getting in the way. For example, the command `esbuild foo/bar/index.js --outbase=. --outdir=out --entry-names=[dir]` previously generated the file `out/foo/bar/.js` but will now generate the file `out/foo/bar.js`.
### [`v0.13.7`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0137)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.6...v0.13.7)
- Minify CSS alpha values correctly ([#1682](https://togithub.com/evanw/esbuild/issues/1682))
When esbuild uses the `rgba()` syntax for a color instead of the 8-character hex code (e.g. when `target` is set to Chrome 61 or earlier), the 0-to-255 integer alpha value must be printed as a floating-point fraction between 0 and 1. The fraction was only printed to three decimal places since that is the minimal number of decimal places required for all 256 different alpha values to be uniquely determined. However, using three decimal places does not necessarily result in the shortest result. For example, `128 / 255` is `0.5019607843137255` which is printed as `".502"` using three decimal places, but `".5"` is equivalent because `round(0.5 * 255) == 128`, so printing `".5"` would be better. With this release, esbuild will always use the minimal numeric representation for the alpha value:
```css
/* Original code */
a { color: #FF800080 }
/* Old output (with --minify --target=chrome61) */
a{color:rgba(255,128,0,.502)}
/* New output (with --minify --target=chrome61) */
a{color:rgba(255,128,0,.5)}
```
- Match node's behavior for core module detection ([#1680](https://togithub.com/evanw/esbuild/issues/1680))
Node has a hard-coded list of core modules (e.g. `fs`) that, when required, short-circuit the module resolution algorithm and instead return the corresponding internal core module object. When you pass `--platform=node` to esbuild, esbuild also implements this short-circuiting behavior and doesn't try to bundle these import paths. This was implemented in esbuild using the existing `external` feature (e.g. essentially `--external:fs`). However, there is an edge case where esbuild's `external` feature behaved differently than node.
Modules specified via esbuild's `external` feature also cause all sub-paths to be excluded as well, so for example `--external:foo` excludes both `foo` and `foo/bar` from the bundle. However, node's core module check is only an exact equality check, so for example `fs` is a core module and bypasses the module resolution algorithm but `fs/foo` is not a core module and causes the module resolution algorithm to search the file system.
This behavior can be used to load a module on the file system with the same name as one of node's core modules. For example, `require('fs/')` will load the module `fs` from the file system instead of loading node's core `fs` module. With this release, esbuild will now match node's behavior in this edge case. This means the external modules that are automatically added by `--platform=node` now behave subtly differently than `--external:`, which allows code that relies on this behavior to be bundled correctly.
- Fix WebAssembly builds on Go 1.17.2+ ([#1684](https://togithub.com/evanw/esbuild/pull/1684))
Go 1.17.2 introduces a change (specifically a [fix for CVE-2021-38297](https://go-review.googlesource.com/c/go/+/354591/)) that causes Go's WebAssembly bootstrap script to throw an error when it's run in situations with many environment variables. One such situation is when the bootstrap script is run inside [GitHub Actions](https://togithub.com/features/actions). This change was introduced because the bootstrap script writes a copy of the environment variables into WebAssembly memory without any bounds checking, and writing more than 4096 bytes of data ends up writing past the end of the buffer and overwriting who-knows-what. So throwing an error in this situation is an improvement. However, this breaks esbuild which previously (at least seemingly) worked fine.
With this release, esbuild's WebAssembly bootstrap script that calls out to Go's WebAssembly bootstrap script will now delete all environment variables except for the ones that esbuild checks for, of which there are currently only four: `NO_COLOR`, `NODE_PATH`, `npm_config_user_agent`, and `WT_SESSION`. This should avoid a crash when esbuild is built using Go 1.17.2+ and should reduce the likelihood of memory corruption when esbuild is built using Go 1.17.1 or earlier. This release also updates the Go version that esbuild ships with to version 1.17.2. Note that this problem only affects the `esbuild-wasm` package. The `esbuild` package is not affected.
See also:
- [https://github.com/golang/go/issues/48797](https://togithub.com/golang/go/issues/48797)
- [https://github.com/golang/go/issues/49011](https://togithub.com/golang/go/issues/49011)
### [`v0.13.6`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0136)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.5...v0.13.6)
- Emit decorators for `declare` class fields ([#1675](https://togithub.com/evanw/esbuild/issues/1675))
In version 3.7, TypeScript introduced the `declare` keyword for class fields that avoids generating any code for that field:
```ts
// TypeScript input
class Foo {
a: number
declare b: number
}
// JavaScript output
class Foo {
a;
}
```
However, it turns out that TypeScript still emits decorators for these omitted fields. With this release, esbuild will now do this too:
```ts
// TypeScript input
class Foo {
@decorator a: number;
@decorator declare b: number;
}
// Old JavaScript output
class Foo {
a;
}
__decorateClass([
decorator
], Foo.prototype, "a", 2);
// New JavaScript output
class Foo {
a;
}
__decorateClass([
decorator
], Foo.prototype, "a", 2);
__decorateClass([
decorator
], Foo.prototype, "b", 2);
```
- Experimental support for esbuild on NetBSD ([#1624](https://togithub.com/evanw/esbuild/pull/1624))
With this release, esbuild now has a published binary executable for [NetBSD](https://www.netbsd.org/) in the [`esbuild-netbsd-64`](https://www.npmjs.com/package/esbuild-netbsd-64) npm package, and esbuild's installer has been modified to attempt to use it when on NetBSD. Hopefully this makes installing esbuild via npm work on NetBSD. This change was contributed by [@gdt](https://togithub.com/gdt).
⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️
- Disable the "esbuild was bundled" warning if `ESBUILD_BINARY_PATH` is provided ([#1678](https://togithub.com/evanw/esbuild/pull/1678))
The `ESBUILD_BINARY_PATH` environment variable allows you to substitute an alternate binary executable for esbuild's JavaScript API. This is useful in certain cases such as when debugging esbuild. The JavaScript API has some code that throws an error if it detects that it was bundled before being run, since bundling prevents esbuild from being able to find the path to its binary executable. However, that error is unnecessary if `ESBUILD_BINARY_PATH` is present because an alternate path has been provided. This release disables the warning when `ESBUILD_BINARY_PATH` is present so that esbuild can be used when bundled as long as you also manually specify `ESBUILD_BINARY_PATH`.
This change was contributed by [@heypiotr](https://togithub.com/heypiotr).
- Remove unused `catch` bindings when minifying ([#1660](https://togithub.com/evanw/esbuild/pull/1660))
With this release, esbuild will now remove unused `catch` bindings when minifying:
```js
// Original code
try {
throw 0;
} catch (e) {
}
// Old output (with --minify)
try{throw 0}catch(t){}
// New output (with --minify)
try{throw 0}catch{}
```
This takes advantage of the new [optional catch binding](https://togithub.com/tc39/proposal-optional-catch-binding) syntax feature that was introduced in ES2019. This minification rule is only enabled when optional catch bindings are supported by the target environment. Specifically, it's not enabled when using `--target=es2018` or older. Make sure to set esbuild's `target` setting correctly when minifying if the code will be running in an older JavaScript environment.
This change was contributed by [@sapphi-red](https://togithub.com/sapphi-red).
### [`v0.13.5`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0135)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.4...v0.13.5)
- Improve watch mode accuracy ([#1113](https://togithub.com/evanw/esbuild/issues/1113))
Watch mode is enabled by `--watch` and causes esbuild to become a long-running process that automatically rebuilds output files when input files are changed. It's implemented by recording all calls to esbuild's internal file system interface and then invalidating the build whenever these calls would return different values. For example, a call to esbuild's internal `ReadFile()` function is considered to be different if either the presence of the file has changed (e.g. the file didn't exist before but now exists) or the presence of the file stayed the same but the content of the file has changed.
Previously esbuild's watch mode operated at the `ReadFile()` and `ReadDirectory()` level. When esbuild checked whether a directory entry existed or not (e.g. whether a directory contains a `node_modules` subdirectory or a `package.json` file), it called `ReadDirectory()` which then caused the build to depend on that directory's set of entries. This meant the build would be invalidated even if a new unrelated entry was added or removed, since that still changes the set of entries. This is problematic when using esbuild in environments that constantly create and destroy temporary directory entries in your project directory. In that case, esbuild's watch mode would constantly rebuild as the directory was constantly considered to be dirty.
With this release, watch mode now operates at the `ReadFile()` and `ReadDirectory().Get()` level. So when esbuild checks whether a directory entry exists or not, the build should now only depend on the presence status for that one directory entry. This should avoid unnecessary rebuilds due to unrelated directory entries being added or removed. The log messages generated using `--watch` will now also mention the specific directory entry whose presence status was changed if a build is invalidated for this reason.
Note that this optimization does not apply to plugins using the `watchDirs` return value because those paths are only specified at the directory level and do not describe individual directory entries. You can use `watchFiles` or `watchDirs` on the individual entries inside the directory to get a similar effect instead.
- Disallow certain uses of `<` in `.mts` and `.cts` files
The upcoming version 4.5 of TypeScript is introducing the `.mts` and `.cts` extensions that turn into the `.mjs` and `.cjs` extensions when compiled. However, unlike the existing `.ts` and `.tsx` extensions, expressions that start with `<` are disallowed when they would be ambiguous depending on whether they are parsed in `.ts` or `.tsx` mode. The ambiguity is caused by the overlap between the syntax for JSX elements and the old deprecated syntax for type casts:
| Syntax | `.ts` | `.tsx` | `.mts`/`.cts` |
|-------------------------------|----------------------|------------------|----------------------|
| `y` | ✅ Type cast | 🚫 Syntax error | 🚫 Syntax error |
| `() => {}` | ✅ Arrow function | 🚫 Syntax error | 🚫 Syntax error |
| `y` | 🚫 Syntax error | ✅ JSX element | 🚫 Syntax error |
| `() => {}` | 🚫 Syntax error | ✅ JSX element | 🚫 Syntax error |
| `() => {}` | 🚫 Syntax error | ✅ JSX element | 🚫 Syntax error |
| `() => {}` | 🚫 Syntax error | ✅ JSX element | 🚫 Syntax error |
| `() => {}` | ✅ Arrow function | ✅ Arrow function | ✅ Arrow function |
| `() => {}` | ✅ Arrow function | ✅ Arrow function | ✅ Arrow function |
This release of esbuild introduces a syntax error for these ambiguous syntax constructs in `.mts` and `.cts` files to match the new behavior of the TypeScript compiler.
- Do not remove empty `@keyframes` rules ([#1665](https://togithub.com/evanw/esbuild/issues/1665))
CSS minification in esbuild automatically removes empty CSS rules, since they have no effect. However, empty `@keyframes` rules still trigger JavaScript animation events so it's incorrect to remove them. To demonstrate that empty `@keyframes` rules still have an effect, here is a bug report for Firefox where it was incorrectly not triggering JavaScript animation events for empty `@keyframes` rules: https://bugzilla.mozilla.org/show_bug.cgi?id=1004377.
With this release, empty `@keyframes` rules are now preserved during minification:
```css
/* Original CSS */
@keyframes foo {
from {}
to {}
}
/* Old output (with --minify) */
/* New output (with --minify) */
@keyframes foo{}
```
This fix was contributed by [@eelco](https://togithub.com/eelco).
- Fix an incorrect duplicate label error ([#1671](https://togithub.com/evanw/esbuild/pull/1671))
When labeling a statement in JavaScript, the label must be unique within the enclosing statements since the label determines the jump target of any labeled `break` or `continue` statement:
```js
// This code is valid
x: y: z: break x;
// This code is invalid
x: y: x: break x;
```
However, an enclosing label with the same name *is* allowed as long as it's located in a different function body. Since `break` and `continue` statements can't jump across function boundaries, the label is not ambiguous. This release fixes a bug where esbuild incorrectly treated this valid code as a syntax error:
```js
// This code is valid, but was incorrectly considered a syntax error
x: (() => {
x: break x;
})();
```
This fix was contributed by [@nevkontakte](https://togithub.com/nevkontakte).
### [`v0.13.4`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0134)
[Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.3...v0.13.4)
- Fix permission issues with the install script ([#1642](https://togithub.com/evanw/esbuild/issues/1642))
The `esbuild` package contains a small JavaScript stub file that implements the CLI (command-line interface). Its only purpose is to spawn the binary esbuild executable as a child process and forward the command-line arguments to it.
The install script contains an optimization that replaces this small JavaScript stub with the actual binary executable at install time to avoid the overhead of unnecessarily creating a new `node` process. This optimization can't be done at package publish time because there is only one `esbuild` package but there are many supported platforms, so the binary executable for the current platform must live outside of the `esbuild` package.
However, the optimization was implemented with an [unlink](https://www.man7.org/linux/man-pages/man2/unlink.2.html) operation followed by a [link](https://www.man7.org/linux/man-pages/man2/link.2.html) operation. This means that if the first step fails, the package is left in a broken state since the JavaScript stub file is deleted but not yet replaced.
With this release, the optimization is now implemented with a [link](https://www.man7.org/linux/man-pages/man2/link.2.html) operation followed by a [rename](https://www.man7.org/linux/man-pages/man2/rename.2.html) operation. This should always leave the package in a working state even if either step fails.
- Add a fallback for `npm install esbuild --no-optional` ([#1647](https://togithub.com/evanw/esbuild/issues/1647))
The installation method for esbuild's platform-specific binary executable was recently changed in version 0.13.0. Before that version esbuild downloaded it in an install script, and after that version esbuild lets the package manager download it using the `optionalDependencies` feature in `package.json`. This change was made because downloading the binary executable in an install script never really fully worked. The reasons are complex but basically there are a variety of edge cases where people people want to install esbuild in environments that they have customized such that downloading esbuild isn't possible. Using `optionalDependencies` instead lets the package manager deal with it instead, which should work fine in all cases (either that or your package manager has a bug, but that's not esbuild's problem).
There is one case where this new installation method doesn't work: if you pass the `--no-optional` flag to npm to disable the `optionalDependencies` feature. If you do this, you prevent esbuild from being installed. This is not a problem with esbuild because you are manually enabling a flag to change npm's behavior such that esbuild doesn't install correctly. However, people still want to do this.
With this release, esbuild will now fall back to the old installation method if the new installation method fails. **THIS MAY NOT WORK.** The new `optionalDependencies` installation method is the only supported way to install esbuild with npm. The old downloading installation method was removed because it doesn't always work. The downloading method is only being provided to try to be helpful but it's not the supported installation method. If you pass `--no-optional` and the download fails due to some environment customization you did, the recommended fix is to just remove the `--no-optional` flag.
- Support the new `.mts` and `.cts` TypeScript file extensions
The upcoming version 4.5 of TypeScript has two new file extensions: `.mts` and `.cts`. Files with these extensions can be imported using the `.mjs` and `.cjs`, respectively. So the statement `import "./foo.mjs"` in TypeScript can actually succeed even if the file `./foo.mjs` doesn't exist on the file system as long as the file `./foo.mts` does exist. The import path with the `.mjs` extension is automatically re-routed to the corresponding file with the `.mts` extension at type-checking time by the TypeScript compiler. See [the TypeScript 4.5 beta announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#new-file-extensions) for details.
With this release, esbuild will also automatically rewrite `.mjs` to `.mts` and `.cjs` to `.cts` when resolving import paths to files on the file system. This should make it possible to bundle code written in this new style. In addition, the extensions `.mts` and `.cts` are now also considered valid TypeScript file extensions by default along with the `.ts` extension.
- Fix invalid CSS minification of `margin` and `padding` ([#1657](https://togithub.com/evanw/esbuild/issues/1657))
CSS minification does collapsing of `margin` and `padding` related properties. For example:
```css
/* Original CSS */
div {
margin: auto;
margin-top: 5px;
margin-left: 5px;
}
/* Minified CSS */
div{margin:5px auto auto 5px}
```
However, while this works for the `auto` keyword, it doesn't work for other keywords. For example:
```css
/* Original CSS */
div {
margin: inherit;
margin-top: 5px;
margin-left: 5px;
}
/* Minified CSS */
div{margin:inherit;margin-top:5px;margin-left:5px}
```
Transforming this to `div{margin:5px inherit inherit 5px}`, as was done in previous releases of esbuild, is an invalid transformation and results in incorrect CSS. This release of esbuild fixes this CSS transformation bug.
Configuration
📅 Schedule: "on the first day of the month" (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.
[ ] If you want to rebase/retry this PR, click this checkbox.
This PR contains the following updates:
0.13.3
->0.13.12
Release Notes
evanw/esbuild
### [`v0.13.12`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01312) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.11...v0.13.12) - Implement initial support for simplifying `calc()` expressions in CSS ([#1607](https://togithub.com/evanw/esbuild/issues/1607)) This release includes basic simplification of `calc()` expressions in CSS when minification is enabled. The approach mainly follows the official CSS specification, which means it should behave the way browsers behave: https://www.w3.org/TR/css-values-4/#calc-func. This is a basic implementation so there are probably some `calc()` expressions that can be reduced by other tools but not by esbuild. This release mainly focuses on setting up the parsing infrastructure for `calc()` expressions to make it straightforward to implement additional simplifications in the future. Here's an example of this new functionality: ```css /* Input CSS */ div { width: calc(60px * 4 - 5px * 2); height: calc(100% / 4); } /* Output CSS (with --minify-syntax) */ div { width: 230px; height: 25%; } ``` Expressions that can't be fully simplified will still be partially simplified into a reduced `calc()` expression: ```css /* Input CSS */ div { width: calc(100% / 5 - 2 * 1em - 2 * 1px); } /* Output CSS (with --minify-syntax) */ div { width: calc(20% - 2em - 2px); } ``` Note that this transformation doesn't attempt to modify any expression containing a `var()` CSS variable reference. These variable references can contain any number of tokens so it's not safe to move forward with a simplification assuming that `var()` is a single token. For example, `calc(2px * var(--x) * 3)` is not transformed into `calc(6px * var(--x))` in case `var(--x)` contains something like `4 + 5px` (`calc(2px * 4 + 5px * 3)` evaluates to `23px` while `calc(6px * 4 + 5px)` evaluates to `29px`). - Fix a crash with a legal comment followed by an import ([#1730](https://togithub.com/evanw/esbuild/issues/1730)) Version 0.13.10 introduced parsing for CSS legal comments but caused a regression in the code that checks whether there are any rules that come before `@import`. This is not desired because browsers ignore `@import` rules after other non-`@import` rules, so esbuild warns you when you do this. However, legal comments are modeled as rules in esbuild's internal AST even though they aren't actual CSS rules, and the code that performs this check wasn't updated. This release fixes the crash. ### [`v0.13.11`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01311) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.10...v0.13.11) - Implement class static blocks ([#1558](https://togithub.com/evanw/esbuild/issues/1558)) This release adds support for a new upcoming JavaScript feature called [class static blocks](https://togithub.com/tc39/proposal-class-static-block) that lets you evaluate code inside of a class body. It looks like this: ```js class Foo { static { this.foo = 123 } } ``` This can be useful when you want to use `try`/`catch` or access private `#name` fields during class initialization. Doing that without this feature is quite hacky and basically involves creating temporary static fields containing immediately-invoked functions and then deleting the fields after class initialization. Static blocks are much more ergonomic and avoid performance loss due to `delete` changing the object shape. Static blocks are transformed for older browsers by moving the static block outside of the class body and into an immediately invoked arrow function after the class definition: ```js // The transformed version of the example code above const _Foo = class { }; let Foo = _Foo; (() => { _Foo.foo = 123; })(); ``` In case you're wondering, the additional `let` variable is to guard against the potential reassignment of `Foo` during evaluation such as what happens below. The value of `this` must be bound to the original class, not to the current value of `Foo`: ```js let bar class Foo { static { bar = () => this } } Foo = null console.log(bar()) // This should not be "null" ``` - Fix issues with `super` property accesses Code containing `super` property accesses may need to be transformed even when they are supported. For example, in ES6 `async` methods are unsupported while `super` properties are supported. An `async` method containing `super` property accesses requires those uses of `super` to be transformed (the `async` function is transformed into a nested generator function and the `super` keyword cannot be used inside nested functions). Previously esbuild transformed `super` property accesses into a function call that returned the corresponding property. However, this was incorrect for uses of `super` that write to the inherited setter since a function call is not a valid assignment target. This release fixes writing to a `super` property: ```js // Original code class Base { set foo(x) { console.log('set foo to', x) } } class Derived extends Base { async bar() { super.foo = 123 } } new Derived().bar() // Old output with --target=es6 (contains a syntax error) class Base { set foo(x) { console.log("set foo to", x); } } class Derived extends Base { bar() { var __super = (key) => super[key]; return __async(this, null, function* () { __super("foo") = 123; }); } } new Derived().bar(); // New output with --target=es6 (works correctly) class Base { set foo(x) { console.log("set foo to", x); } } class Derived extends Base { bar() { var __superSet = (key, value) => super[key] = value; return __async(this, null, function* () { __superSet("foo", 123); }); } } new Derived().bar(); ``` All known edge cases for assignment to a `super` property should now be covered including destructuring assignment and using the unary assignment operators with BigInts. In addition, this release also fixes a bug where a `static` class field containing a `super` property access was not transformed when it was moved outside of the class body, which can happen when `static` class fields aren't supported. ```js // Original code class Base { static get foo() { return 123 } } class Derived extends Base { static bar = super.foo } // Old output with --target=es6 (contains a syntax error) class Base { static get foo() { return 123; } } class Derived extends Base { } __publicField(Derived, "bar", super.foo); // New output with --target=es6 (works correctly) class Base { static get foo() { return 123; } } const _Derived = class extends Base { }; let Derived = _Derived; __publicField(Derived, "bar", __superStaticGet(_Derived, "foo")); ``` All known edge cases for `super` inside `static` class fields should be handled including accessing `super` after prototype reassignment of the enclosing class object. ### [`v0.13.10`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#01310) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.9...v0.13.10) - Implement legal comment preservation for CSS ([#1539](https://togithub.com/evanw/esbuild/issues/1539)) This release adds support for legal comments in CSS the same way they are already supported for JS. A legal comment is one that starts with `/*!` or that contains the text `@license` or `@preserve`. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code. The specific behavior is controlled via `--legal-comments=` in the CLI and `legalComments` in the JS API, which can be set to any of the following options: - `none`: Do not preserve any legal comments - `inline`: Preserve all rule-level legal comments - `eof`: Move all rule-level legal comments to the end of the file - `linked`: Move all rule-level legal comments to a `.LEGAL.txt` file and link to them with a comment - `external`: Move all rule-level legal comments to a `.LEGAL.txt` file but to not link to them The default behavior is `eof` when bundling and `inline` otherwise. - Allow uppercase `es*` targets ([#1717](https://togithub.com/evanw/esbuild/issues/1717)) With this release, you can now use target names such as `ESNext` instead of `esnext` as the target name in the CLI and JS API. This is important because people don't want to have to call `.toLowerCase()` on target strings from TypeScript's `tsconfig.json` file before passing it to esbuild (TypeScript uses case-agnostic target names). This feature was contributed by [@timse](https://togithub.com/timse). - Update to Unicode 14.0.0 The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 13.0.0 to the newly release Unicode version 14.0.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode14.0.0/#Summary for more information about the changes. ### [`v0.13.9`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0139) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.8...v0.13.9) - Add support for `imports` in `package.json` ([#1691](https://togithub.com/evanw/esbuild/issues/1691)) This release adds basic support for the `imports` field in `package.json`. It behaves similarly to the `exports` field but only applies to import paths that start with `#`. The `imports` field provides a way for a package to remap its own internal imports for itself, while the `exports` field provides a way for a package to remap its external exports for other packages. This is useful because the `imports` field respects the currently-configured conditions which means that the import mapping can change at run-time. For example: $ cat entry.mjs import '#example' $ cat package.json { "imports": { "#example": { "foo": "./example.foo.mjs", "default": "./example.mjs" } } } $ cat example.foo.mjs console.log('foo is enabled') $ cat example.mjs console.log('foo is disabled') $ node entry.mjs foo is disabled $ node --conditions=foo entry.mjs foo is enabled Now that esbuild supports this feature too, import paths starting with `#` and any provided conditions will be respected when bundling: $ esbuild --bundle entry.mjs | node foo is disabled $ esbuild --conditions=foo --bundle entry.mjs | node foo is enabled - Fix using `npm rebuild` with the `esbuild` package ([#1703](https://togithub.com/evanw/esbuild/issues/1703)) Version 0.13.4 accidentally introduced a regression in the install script where running `npm rebuild` multiple times could fail after the second time. The install script creates a copy of the binary executable using [`link`](https://man7.org/linux/man-pages/man2/link.2.html) followed by [`rename`](https://www.man7.org/linux/man-pages/man2/rename.2.html). Using `link` creates a hard link which saves space on the file system, and `rename` is used for safety since it atomically replaces the destination. However, the `rename` syscall has an edge case where it silently fails if the source and destination are both the same link. This meant that the install script would fail after being run twice in a row. With this release, the install script now deletes the source after calling `rename` in case it has silently failed, so this issue should now be fixed. It should now be safe to use `npm rebuild` with the `esbuild` package. - Fix invalid CSS minification of `border-radius` ([#1702](https://togithub.com/evanw/esbuild/issues/1702)) CSS minification does collapsing of `border-radius` related properties. For example: ```css /* Original CSS */ div { border-radius: 1px; border-top-left-radius: 5px; } /* Minified CSS */ div{border-radius:5px 1px 1px} ``` However, this only works for numeric tokens, not identifiers. For example: ```css /* Original CSS */ div { border-radius: 1px; border-top-left-radius: inherit; } /* Minified CSS */ div{border-radius:1px;border-top-left-radius:inherit} ``` Transforming this to `div{border-radius:inherit 1px 1px}`, as was done in previous releases of esbuild, is an invalid transformation and results in incorrect CSS. This release of esbuild fixes this CSS transformation bug. ### [`v0.13.8`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0138) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.7...v0.13.8) - Fix `super` inside arrow function inside lowered `async` function ([#1425](https://togithub.com/evanw/esbuild/issues/1425)) When an `async` function is transformed into a regular function for target environments that don't support `async` such as `--target=es6`, references to `super` inside that function must be transformed too since the `async`-to-regular function transformation moves the function body into a nested function, so the `super` references are no longer syntactically valid. However, this transform didn't handle an edge case and `super` references inside of an arrow function were overlooked. This release fixes this bug: ```js // Original code class Foo extends Bar { async foo() { return () => super.foo() } } // Old output (with --target=es6) class Foo extends Bar { foo() { return __async(this, null, function* () { return () => super.foo(); }); } } // New output (with --target=es6) class Foo extends Bar { foo() { var __super = (key) => super[key]; return __async(this, null, function* () { return () => __super("foo").call(this); }); } } ``` - Remove the implicit `/` after `[dir]` in entry names ([#1661](https://togithub.com/evanw/esbuild/issues/1661)) The "entry names" feature lets you customize the way output file names are generated. The `[dir]` and `[name]` placeholders are filled in with the directory name and file name of the corresponding entry point file, respectively. Previously `--entry-names=[dir]/[name]` and `--entry-names=[dir][name]` behaved the same because the value used for `[dir]` always had an implicit trailing slash, since it represents a directory. However, some people want to be able to remove the file name with `--entry-names=[dir]` and the implicit trailing slash gets in the way. With this release, you can now use the `[dir]` placeholder without an implicit trailing slash getting in the way. For example, the command `esbuild foo/bar/index.js --outbase=. --outdir=out --entry-names=[dir]` previously generated the file `out/foo/bar/.js` but will now generate the file `out/foo/bar.js`. ### [`v0.13.7`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0137) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.6...v0.13.7) - Minify CSS alpha values correctly ([#1682](https://togithub.com/evanw/esbuild/issues/1682)) When esbuild uses the `rgba()` syntax for a color instead of the 8-character hex code (e.g. when `target` is set to Chrome 61 or earlier), the 0-to-255 integer alpha value must be printed as a floating-point fraction between 0 and 1. The fraction was only printed to three decimal places since that is the minimal number of decimal places required for all 256 different alpha values to be uniquely determined. However, using three decimal places does not necessarily result in the shortest result. For example, `128 / 255` is `0.5019607843137255` which is printed as `".502"` using three decimal places, but `".5"` is equivalent because `round(0.5 * 255) == 128`, so printing `".5"` would be better. With this release, esbuild will always use the minimal numeric representation for the alpha value: ```css /* Original code */ a { color: #FF800080 } /* Old output (with --minify --target=chrome61) */ a{color:rgba(255,128,0,.502)} /* New output (with --minify --target=chrome61) */ a{color:rgba(255,128,0,.5)} ``` - Match node's behavior for core module detection ([#1680](https://togithub.com/evanw/esbuild/issues/1680)) Node has a hard-coded list of core modules (e.g. `fs`) that, when required, short-circuit the module resolution algorithm and instead return the corresponding internal core module object. When you pass `--platform=node` to esbuild, esbuild also implements this short-circuiting behavior and doesn't try to bundle these import paths. This was implemented in esbuild using the existing `external` feature (e.g. essentially `--external:fs`). However, there is an edge case where esbuild's `external` feature behaved differently than node. Modules specified via esbuild's `external` feature also cause all sub-paths to be excluded as well, so for example `--external:foo` excludes both `foo` and `foo/bar` from the bundle. However, node's core module check is only an exact equality check, so for example `fs` is a core module and bypasses the module resolution algorithm but `fs/foo` is not a core module and causes the module resolution algorithm to search the file system. This behavior can be used to load a module on the file system with the same name as one of node's core modules. For example, `require('fs/')` will load the module `fs` from the file system instead of loading node's core `fs` module. With this release, esbuild will now match node's behavior in this edge case. This means the external modules that are automatically added by `--platform=node` now behave subtly differently than `--external:`, which allows code that relies on this behavior to be bundled correctly. - Fix WebAssembly builds on Go 1.17.2+ ([#1684](https://togithub.com/evanw/esbuild/pull/1684)) Go 1.17.2 introduces a change (specifically a [fix for CVE-2021-38297](https://go-review.googlesource.com/c/go/+/354591/)) that causes Go's WebAssembly bootstrap script to throw an error when it's run in situations with many environment variables. One such situation is when the bootstrap script is run inside [GitHub Actions](https://togithub.com/features/actions). This change was introduced because the bootstrap script writes a copy of the environment variables into WebAssembly memory without any bounds checking, and writing more than 4096 bytes of data ends up writing past the end of the buffer and overwriting who-knows-what. So throwing an error in this situation is an improvement. However, this breaks esbuild which previously (at least seemingly) worked fine. With this release, esbuild's WebAssembly bootstrap script that calls out to Go's WebAssembly bootstrap script will now delete all environment variables except for the ones that esbuild checks for, of which there are currently only four: `NO_COLOR`, `NODE_PATH`, `npm_config_user_agent`, and `WT_SESSION`. This should avoid a crash when esbuild is built using Go 1.17.2+ and should reduce the likelihood of memory corruption when esbuild is built using Go 1.17.1 or earlier. This release also updates the Go version that esbuild ships with to version 1.17.2. Note that this problem only affects the `esbuild-wasm` package. The `esbuild` package is not affected. See also: - [https://github.com/golang/go/issues/48797](https://togithub.com/golang/go/issues/48797) - [https://github.com/golang/go/issues/49011](https://togithub.com/golang/go/issues/49011) ### [`v0.13.6`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0136) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.5...v0.13.6) - Emit decorators for `declare` class fields ([#1675](https://togithub.com/evanw/esbuild/issues/1675)) In version 3.7, TypeScript introduced the `declare` keyword for class fields that avoids generating any code for that field: ```ts // TypeScript input class Foo { a: number declare b: number } // JavaScript output class Foo { a; } ``` However, it turns out that TypeScript still emits decorators for these omitted fields. With this release, esbuild will now do this too: ```ts // TypeScript input class Foo { @decorator a: number; @decorator declare b: number; } // Old JavaScript output class Foo { a; } __decorateClass([ decorator ], Foo.prototype, "a", 2); // New JavaScript output class Foo { a; } __decorateClass([ decorator ], Foo.prototype, "a", 2); __decorateClass([ decorator ], Foo.prototype, "b", 2); ``` - Experimental support for esbuild on NetBSD ([#1624](https://togithub.com/evanw/esbuild/pull/1624)) With this release, esbuild now has a published binary executable for [NetBSD](https://www.netbsd.org/) in the [`esbuild-netbsd-64`](https://www.npmjs.com/package/esbuild-netbsd-64) npm package, and esbuild's installer has been modified to attempt to use it when on NetBSD. Hopefully this makes installing esbuild via npm work on NetBSD. This change was contributed by [@gdt](https://togithub.com/gdt). ⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️ - Disable the "esbuild was bundled" warning if `ESBUILD_BINARY_PATH` is provided ([#1678](https://togithub.com/evanw/esbuild/pull/1678)) The `ESBUILD_BINARY_PATH` environment variable allows you to substitute an alternate binary executable for esbuild's JavaScript API. This is useful in certain cases such as when debugging esbuild. The JavaScript API has some code that throws an error if it detects that it was bundled before being run, since bundling prevents esbuild from being able to find the path to its binary executable. However, that error is unnecessary if `ESBUILD_BINARY_PATH` is present because an alternate path has been provided. This release disables the warning when `ESBUILD_BINARY_PATH` is present so that esbuild can be used when bundled as long as you also manually specify `ESBUILD_BINARY_PATH`. This change was contributed by [@heypiotr](https://togithub.com/heypiotr). - Remove unused `catch` bindings when minifying ([#1660](https://togithub.com/evanw/esbuild/pull/1660)) With this release, esbuild will now remove unused `catch` bindings when minifying: ```js // Original code try { throw 0; } catch (e) { } // Old output (with --minify) try{throw 0}catch(t){} // New output (with --minify) try{throw 0}catch{} ``` This takes advantage of the new [optional catch binding](https://togithub.com/tc39/proposal-optional-catch-binding) syntax feature that was introduced in ES2019. This minification rule is only enabled when optional catch bindings are supported by the target environment. Specifically, it's not enabled when using `--target=es2018` or older. Make sure to set esbuild's `target` setting correctly when minifying if the code will be running in an older JavaScript environment. This change was contributed by [@sapphi-red](https://togithub.com/sapphi-red). ### [`v0.13.5`](https://togithub.com/evanw/esbuild/blob/master/CHANGELOG.md#0135) [Compare Source](https://togithub.com/evanw/esbuild/compare/v0.13.4...v0.13.5) - Improve watch mode accuracy ([#1113](https://togithub.com/evanw/esbuild/issues/1113)) Watch mode is enabled by `--watch` and causes esbuild to become a long-running process that automatically rebuilds output files when input files are changed. It's implemented by recording all calls to esbuild's internal file system interface and then invalidating the build whenever these calls would return different values. For example, a call to esbuild's internal `ReadFile()` function is considered to be different if either the presence of the file has changed (e.g. the file didn't exist before but now exists) or the presence of the file stayed the same but the content of the file has changed. Previously esbuild's watch mode operated at the `ReadFile()` and `ReadDirectory()` level. When esbuild checked whether a directory entry existed or not (e.g. whether a directory contains a `node_modules` subdirectory or a `package.json` file), it called `ReadDirectory()` which then caused the build to depend on that directory's set of entries. This meant the build would be invalidated even if a new unrelated entry was added or removed, since that still changes the set of entries. This is problematic when using esbuild in environments that constantly create and destroy temporary directory entries in your project directory. In that case, esbuild's watch mode would constantly rebuild as the directory was constantly considered to be dirty. With this release, watch mode now operates at the `ReadFile()` and `ReadDirectory().Get()` level. So when esbuild checks whether a directory entry exists or not, the build should now only depend on the presence status for that one directory entry. This should avoid unnecessary rebuilds due to unrelated directory entries being added or removed. The log messages generated using `--watch` will now also mention the specific directory entry whose presence status was changed if a build is invalidated for this reason. Note that this optimization does not apply to plugins using the `watchDirs` return value because those paths are only specified at the directory level and do not describe individual directory entries. You can use `watchFiles` or `watchDirs` on the individual entries inside the directory to get a similar effect instead. - Disallow certain uses of `<` in `.mts` and `.cts` files The upcoming version 4.5 of TypeScript is introducing the `.mts` and `.cts` extensions that turn into the `.mjs` and `.cjs` extensions when compiled. However, unlike the existing `.ts` and `.tsx` extensions, expressions that start with `<` are disallowed when they would be ambiguous depending on whether they are parsed in `.ts` or `.tsx` mode. The ambiguity is caused by the overlap between the syntax for JSX elements and the old deprecated syntax for type casts: | Syntax | `.ts` | `.tsx` | `.mts`/`.cts` | |-------------------------------|----------------------|------------------|----------------------| | `Configuration
📅 Schedule: "on the first day of the month" (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.