github.com/evanw/esbuild@v0.21.4/CHANGELOG-2022.md (about)

     1  # Changelog: 2022
     2  
     3  This changelog documents all esbuild versions published in the year 2022 (versions 0.14.11 through 0.16.12).
     4  
     5  ## 0.16.12
     6  
     7  * Loader defaults to `js` for extensionless files ([#2776](https://github.com/evanw/esbuild/issues/2776))
     8  
     9      Certain packages contain files without an extension. For example, the `yargs` package contains the file `yargs/yargs` which has no extension. Node, Webpack, and Parcel can all understand code that imports `yargs/yargs` because they assume that the file is JavaScript. However, esbuild was previously unable to understand this code because it relies on the file extension to tell it how to interpret the file. With this release, esbuild will now assume files without an extension are JavaScript files. This can be customized by setting the loader for `""` (the empty string, representing files without an extension) to another loader. For example, if you want files without an extension to be treated as CSS instead, you can do that like this:
    10  
    11      * CLI:
    12  
    13          ```
    14          esbuild --bundle --loader:=css
    15          ```
    16  
    17      * JS:
    18  
    19          ```js
    20          esbuild.build({
    21            bundle: true,
    22            loader: { '': 'css' },
    23          })
    24          ```
    25  
    26      * Go:
    27  
    28          ```go
    29          api.Build(api.BuildOptions{
    30            Bundle: true,
    31            Loader: map[string]api.Loader{"": api.LoaderCSS},
    32          })
    33          ```
    34  
    35      In addition, the `"type"` field in `package.json` files now only applies to files with an explicit `.js`, `.jsx`, `.ts`, or `.tsx` extension. Previously it was incorrectly applied by esbuild to all files that had an extension other than `.mjs`, `.mts`, `.cjs`, or `.cts` including extensionless files. So for example an extensionless file in a `"type": "module"` package is now treated as CommonJS instead of ESM.
    36  
    37  ## 0.16.11
    38  
    39  * Avoid a syntax error in the presence of direct `eval` ([#2761](https://github.com/evanw/esbuild/issues/2761))
    40  
    41      The behavior of nested `function` declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested `function` declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested `function` declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:
    42  
    43      ```js
    44      // Original code
    45      if (true) {
    46        function foo() {}
    47        console.log(!!foo)
    48        foo = null
    49        console.log(!!foo)
    50      }
    51      console.log(!!foo)
    52  
    53      // Transformed code
    54      if (true) {
    55        let foo2 = function() {
    56        };
    57        var foo = foo2;
    58        console.log(!!foo2);
    59        foo2 = null;
    60        console.log(!!foo2);
    61      }
    62      console.log(!!foo);
    63      ```
    64  
    65      In the above example, the original code should print `true false true` because it's not run in strict mode (it doesn't contain `"use strict"` and is not an ES module). The code that esbuild generates has been transformed such that it prints `true false true` regardless of whether it's run in strict mode or not.
    66  
    67      However, this transformation is impossible if the code contains direct `eval` because direct `eval` "poisons" all containing scopes by preventing anything in those scopes from being renamed. That prevents esbuild from splitting up accesses to `foo` into two separate variables with different names. Previously esbuild still did this transformation but with two variables both named `foo`, which is a syntax error. With this release esbuild will now skip doing this transformation when direct `eval` is present to avoid generating code with a syntax error. This means that the generated code may no longer behave as intended since the behavior depends on the run-time strict mode setting instead of the strict mode setting present in the original source code. To fix this problem, you will need to remove the use of direct `eval`.
    68  
    69  * Fix a bundling scenario involving multiple symlinks ([#2773](https://github.com/evanw/esbuild/issues/2773), [#2774](https://github.com/evanw/esbuild/issues/2774))
    70  
    71      This release contains a fix for a bundling scenario involving an import path where multiple path segments are symlinks. Previously esbuild was unable to resolve certain import paths in this scenario, but these import paths should now work starting with this release. This fix was contributed by [@onebytegone](https://github.com/onebytegone).
    72  
    73  ## 0.16.10
    74  
    75  * Change the default "legal comment" behavior again ([#2745](https://github.com/evanw/esbuild/issues/2745))
    76  
    77      The legal comments feature automatically gathers comments containing `@license` or `@preserve` and puts the comments somewhere (either in the generated code or in a separate file). This behavior used to be on by default but was disabled by default in version 0.16.0 because automatically inserting comments is potentially confusing and misleading. These comments can appear to be assigning the copyright of your code to another entity. And this behavior can be especially problematic if it happens automatically by default since you may not even be aware of it happening. For example, if you bundle the TypeScript compiler the preserving legal comments means your source code would contain this comment, which appears to be assigning the copyright of all of your code to Microsoft:
    78  
    79      ```js
    80      /*! *****************************************************************************
    81      Copyright (c) Microsoft Corporation. All rights reserved.
    82      Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    83      this file except in compliance with the License. You may obtain a copy of the
    84      License at http://www.apache.org/licenses/LICENSE-2.0
    85  
    86      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    87      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    88      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    89      MERCHANTABLITY OR NON-INFRINGEMENT.
    90  
    91      See the Apache Version 2.0 License for specific language governing permissions
    92      and limitations under the License.
    93      ***************************************************************************** */
    94      ```
    95  
    96      However, people have asked for this feature to be re-enabled by default. To resolve the confusion about what these comments are applying to, esbuild's default behavior will now be to attempt to describe which package the comments are coming from. So while this feature has been re-enabled by default, the output will now look something like this instead:
    97  
    98      ```js
    99      /*! Bundled license information:
   100  
   101      typescript/lib/typescript.js:
   102        (*! *****************************************************************************
   103        Copyright (c) Microsoft Corporation. All rights reserved.
   104        Licensed under the Apache License, Version 2.0 (the "License"); you may not use
   105        this file except in compliance with the License. You may obtain a copy of the
   106        License at http://www.apache.org/licenses/LICENSE-2.0
   107  
   108        THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   109        KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
   110        WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
   111        MERCHANTABLITY OR NON-INFRINGEMENT.
   112  
   113        See the Apache Version 2.0 License for specific language governing permissions
   114        and limitations under the License.
   115        ***************************************************************************** *)
   116      */
   117      ```
   118  
   119      Note that you can still customize this behavior with the `--legal-comments=` flag. For example, you can use `--legal-comments=none` to turn this off, or you can use `--legal-comments=linked` to put these comments in a separate `.LEGAL.txt` file instead.
   120  
   121  * Enable `external` legal comments with the transform API ([#2390](https://github.com/evanw/esbuild/issues/2390))
   122  
   123      Previously esbuild's transform API only supported `none`, `inline`, or `eof` legal comments. With this release, `external` legal comments are now also supported with the transform API. This only applies to the JS and Go APIs, not to the CLI, and looks like this:
   124  
   125      * JS:
   126  
   127          ```js
   128          const { code, legalComments } = await esbuild.transform(input, {
   129            legalComments: 'external',
   130          })
   131          ```
   132  
   133      * Go:
   134  
   135          ```go
   136          result := api.Transform(input, api.TransformOptions{
   137            LegalComments: api.LegalCommentsEndOfFile,
   138          })
   139          code := result.Code
   140          legalComments := result.LegalComments
   141          ```
   142  
   143  * Fix duplicate function declaration edge cases ([#2757](https://github.com/evanw/esbuild/issues/2757))
   144  
   145      The change in the previous release to forbid duplicate function declarations in certain cases accidentally forbid some edge cases that should have been allowed. Specifically duplicate function declarations are forbidden in nested blocks in strict mode and at the top level of modules, but are allowed when they are declared at the top level of function bodies. This release fixes the regression by re-allowing the last case.
   146  
   147  * Allow package subpaths with `alias` ([#2715](https://github.com/evanw/esbuild/issues/2715))
   148  
   149      Previously the names passed to the `alias` feature had to be the name of a package (with or without a package scope). With this release, you can now also use the `alias` feature with package subpaths. So for example you can now create an alias that substitutes `@org/pkg/lib` with something else.
   150  
   151  ## 0.16.9
   152  
   153  * Update to Unicode 15.0.0
   154  
   155      The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 14.0.0 to the newly-released Unicode version 15.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/Unicode15.0.0/#Summary for more information about the changes.
   156  
   157  * Disallow duplicate lexically-declared names in nested blocks and in strict mode
   158  
   159      In strict mode or in a nested block, it's supposed to be a syntax error to declare two symbols with the same name unless all duplicate entries are either `function` declarations or all `var` declarations. However, esbuild was overly permissive and allowed this when duplicate entries were either `function` declarations or `var` declarations (even if they were mixed). This check has now been made more restrictive to match the JavaScript specification:
   160  
   161      ```js
   162      // JavaScript allows this
   163      var a
   164      function a() {}
   165      {
   166        var b
   167        var b
   168        function c() {}
   169        function c() {}
   170      }
   171  
   172      // JavaScript doesn't allow this
   173      {
   174        var d
   175        function d() {}
   176      }
   177      ```
   178  
   179  * Add a type declaration for the new `empty` loader ([#2755](https://github.com/evanw/esbuild/pull/2755))
   180  
   181      I forgot to add this in the previous release. It has now been added.
   182  
   183      This fix was contributed by [@fz6m](https://github.com/fz6m).
   184  
   185  * Add support for the `v` flag in regular expression literals
   186  
   187      People are currently working on adding a `v` flag to JavaScript regular expresions. You can read more about this flag here: https://v8.dev/features/regexp-v-flag. This release adds support for parsing this flag, so esbuild will now no longer consider regular expression literals with this flag to be a syntax error. If the target is set to something other than `esnext`, esbuild will transform regular expression literals containing this flag into a `new RegExp()` constructor call so the resulting code doesn't have a syntax error. This enables you to provide a polyfill for `RegExp` that implements the `v` flag to get your code to work at run-time. While esbuild doesn't typically adopt proposals until they're already shipping in a real JavaScript run-time, I'm adding it now because a) esbuild's implementation doesn't need to change as the proposal evolves, b) this isn't really new syntax since regular expression literals already have flags, and c) esbuild's implementation is a trivial pass-through anyway.
   188  
   189  * Avoid keeping the name of classes with static `name` properties
   190  
   191      The `--keep-names` property attempts to preserve the original value of the `name` property for functions and classes even when identifiers are renamed by the minifier or to avoid a name collision. This is currently done by generating code to assign a string to the `name` property on the function or class object. However, this should not be done for classes with a static `name` property since in that case the explicitly-defined `name` property overwrites the automatically-generated class name. With this release, esbuild will now no longer attempt to preserve the `name` property for classes with a static `name` property.
   192  
   193  ## 0.16.8
   194  
   195  * Allow plugins to resolve injected files ([#2754](https://github.com/evanw/esbuild/issues/2754))
   196  
   197      Previously paths passed to the `inject` feature were always interpreted as file system paths. This meant that `onResolve` plugins would not be run for them and esbuild's default path resolver would always be used. This meant that the `inject` feature couldn't be used in the browser since the browser doesn't have access to a file system. This release runs paths passed to `inject` through esbuild's full path resolution pipeline so plugins now have a chance to handle them using `onResolve` callbacks. This makes it possible to write a plugin that makes esbuild's `inject` work in the browser.
   198  
   199  * Add the `empty` loader ([#1541](https://github.com/evanw/esbuild/issues/1541), [#2753](https://github.com/evanw/esbuild/issues/2753))
   200  
   201      The new `empty` loader tells esbuild to pretend that a file is empty. So for example `--loader:.css=empty` effectively skips all imports of `.css` files in JavaScript so that they aren't included in the bundle, since `import "./some-empty-file"` in JavaScript doesn't bundle anything. You can also use the `empty` loader to remove asset references in CSS files. For example `--loader:.png=empty` causes esbuild to replace asset references such as `url(image.png)` with `url()` so that they are no longer included in the resulting style sheet.
   202  
   203  * Fix `</script>` and `</style>` escaping for non-default targets ([#2748](https://github.com/evanw/esbuild/issues/2748))
   204  
   205      The change in version 0.16.0 to give control over `</script>` escaping via `--supported:inline-script=false` or `--supported:inline-script=true` accidentally broke automatic escaping of `</script>` when an explicit `target` setting is specified. This release restores the correct automatic escaping of `</script>` (which should not depend on what `target` is set to).
   206  
   207  * Enable the `exports` field with `NODE_PATHS` ([#2752](https://github.com/evanw/esbuild/issues/2752))
   208  
   209      Node has a rarely-used feature where you can extend the set of directories that node searches for packages using the `NODE_PATHS` environment variable. While esbuild supports this too, previously it only supported the old `main` field path resolution but did not support the new `exports` field package resolution. This release makes the path resolution rules the same again for both `node_modules` directories and `NODE_PATHS` directories.
   210  
   211  ## 0.16.7
   212  
   213  * Include `file` loader strings in metafile imports ([#2731](https://github.com/evanw/esbuild/issues/2731))
   214  
   215      Bundling a file with the `file` loader copies that file to the output directory and imports a module with the path to the copied file in the `default` export. Previously when bundling with the `file` loader, there was no reference in the metafile from the JavaScript file containing the path string to the copied file. With this release, there will now be a reference in the metafile in the `imports` array with the kind `file-loader`:
   216  
   217      ```diff
   218       {
   219         ...
   220         "outputs": {
   221           "out/image-55CCFTCE.svg": {
   222             ...
   223           },
   224           "out/entry.js": {
   225             "imports": [
   226      +        {
   227      +          "path": "out/image-55CCFTCE.svg",
   228      +          "kind": "file-loader"
   229      +        }
   230             ],
   231             ...
   232           }
   233         }
   234       }
   235      ```
   236  
   237  * Fix byte counts in metafile regarding references to other output files ([#2071](https://github.com/evanw/esbuild/issues/2071))
   238  
   239      Previously files that contained references to other output files had slightly incorrect metadata for the byte counts of input files which contributed to that output file. So for example if `app.js` imports `image.png` using the file loader and esbuild generates `out.js` and `image-LSAMBFUD.png`, the metadata for how many bytes of `out.js` are from `app.js` was slightly off (the metadata for the byte count of `out.js` was still correct). The reason is because esbuild substitutes the final paths for references between output files toward the end of the build to handle cyclic references, and the byte counts needed to be adjusted as well during the path substitution. This release fixes these byte counts (specifically the `bytesInOutput` values).
   240  
   241  * The alias feature now strips a trailing slash ([#2730](https://github.com/evanw/esbuild/issues/2730))
   242  
   243      People sometimes add a trailing slash to the name of one of node's built-in modules to force node to import from the file system instead of importing the built-in module. For example, importing `util` imports node's built-in module called `util` but importing `util/` tries to find a package called `util` on the file system. Previously attempting to use esbuild's package alias feature to replace imports to `util` with a specific file would fail because the file path would also gain a trailing slash (e.g. mapping `util` to `./file.js` turned `util/` into `./file.js/`). With this release, esbuild will now omit the path suffix if it's a single trailing slash, which should now allow you to successfully apply aliases to these import paths.
   244  
   245  ## 0.16.6
   246  
   247  * Do not mark subpath imports as external with `--packages=external` ([#2741](https://github.com/evanw/esbuild/issues/2741))
   248  
   249      Node has a feature called [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) where special import paths that start with `#` are resolved using the `imports` field in the `package.json` file of the enclosing package. The intent of the newly-added `--packages=external` setting is to exclude a package's dependencies from the bundle. Since a package's subpath imports are only accessible within that package, it's wrong for them to be affected by `--packages=external`. This release changes esbuild so that `--packages=external` no longer affects subpath imports.
   250  
   251  * Forbid invalid numbers in JSON files
   252  
   253      Previously esbuild parsed numbers in JSON files using the same syntax as JavaScript. But starting from this release, esbuild will now parse them with JSON syntax instead. This means the following numbers are no longer allowed by esbuild in JSON files:
   254  
   255      * Legacy octal literals (non-zero integers starting with `0`)
   256      * The `0b`, `0o`, and `0x` numeric prefixes
   257      * Numbers containing `_` such as `1_000`
   258      * Leading and trailing `.` such as `0.` and `.0`
   259      * Numbers with a space after the `-` such as `- 1`
   260  
   261  * Add external imports to metafile ([#905](https://github.com/evanw/esbuild/issues/905), [#1768](https://github.com/evanw/esbuild/issues/1768), [#1933](https://github.com/evanw/esbuild/issues/1933), [#1939](https://github.com/evanw/esbuild/issues/1939))
   262  
   263      External imports now appear in `imports` arrays in the metafile (which is present when bundling with `metafile: true`) next to normal imports, but additionally have `external: true` to set them apart. This applies both to files in the `inputs` section and the `outputs` section. Here's an example:
   264  
   265      ```diff
   266       {
   267         "inputs": {
   268           "style.css": {
   269             "bytes": 83,
   270             "imports": [
   271      +        {
   272      +          "path": "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css",
   273      +          "kind": "import-rule",
   274      +          "external": true
   275      +        }
   276             ]
   277           },
   278           "app.js": {
   279             "bytes": 100,
   280             "imports": [
   281      +        {
   282      +          "path": "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js",
   283      +          "kind": "import-statement",
   284      +          "external": true
   285      +        },
   286               {
   287                 "path": "style.css",
   288                 "kind": "import-statement"
   289               }
   290             ]
   291           }
   292         },
   293         "outputs": {
   294           "out/app.js": {
   295             "imports": [
   296      +        {
   297      +          "path": "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js",
   298      +          "kind": "require-call",
   299      +          "external": true
   300      +        }
   301             ],
   302             "exports": [],
   303             "entryPoint": "app.js",
   304             "cssBundle": "out/app.css",
   305             "inputs": {
   306               "app.js": {
   307                 "bytesInOutput": 113
   308               },
   309               "style.css": {
   310                 "bytesInOutput": 0
   311               }
   312             },
   313             "bytes": 528
   314           },
   315           "out/app.css": {
   316             "imports": [
   317      +        {
   318      +          "path": "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css",
   319      +          "kind": "import-rule",
   320      +          "external": true
   321      +        }
   322             ],
   323             "inputs": {
   324               "style.css": {
   325                 "bytesInOutput": 0
   326               }
   327             },
   328             "bytes": 100
   329           }
   330         }
   331       }
   332      ```
   333  
   334      One additional useful consequence of this is that the `imports` array is now populated when bundling is disabled. So you can now use esbuild with bundling disabled to inspect a file's imports.
   335  
   336  ## 0.16.5
   337  
   338  * Make it easy to exclude all packages from a bundle ([#1958](https://github.com/evanw/esbuild/issues/1958), [#1975](https://github.com/evanw/esbuild/issues/1975), [#2164](https://github.com/evanw/esbuild/issues/2164), [#2246](https://github.com/evanw/esbuild/issues/2246), [#2542](https://github.com/evanw/esbuild/issues/2542))
   339  
   340      When bundling for node, it's often necessary to exclude npm packages from the bundle since they weren't designed with esbuild bundling in mind and don't work correctly after being bundled. For example, they may use `__dirname` and run-time file system calls to load files, which doesn't work after bundling with esbuild. Or they may compile a native `.node` extension that has similar expectations about the layout of the file system that are no longer true after bundling (even if the `.node` extension is copied next to the bundle).
   341  
   342      The way to get this to work with esbuild is to use the `--external:` flag. For example, the [`fsevents`](https://www.npmjs.com/package/fsevents) package contains a native `.node` extension and shouldn't be bundled. To bundle code that uses it, you can pass `--external:fsevents` to esbuild to exclude it from your bundle. You will then need to ensure that the `fsevents` package is still present when you run your bundle (e.g. by publishing your bundle to npm as a package with a dependency on `fsevents`).
   343  
   344      It was possible to automatically do this for all of your dependencies, but it was inconvenient. You had to write some code that read your `package.json` file and passed the keys of the `dependencies`, `devDependencies`, `peerDependencies`, and/or `optionalDependencies` maps to esbuild as external packages (either that or write a plugin to mark all package paths as external). Previously esbuild's recommendation for making this easier was to do `--external:./node_modules/*` (added in version 0.14.13). However, this was a bad idea because it caused compatibility problems with many node packages as it caused esbuild to mark the post-resolve path as external instead of the pre-resolve path. Doing that could break packages that are published as both CommonJS and ESM if esbuild's bundler is also used to do a module format conversion.
   345  
   346      With this release, you can now do the following to automatically exclude all packages from your bundle:
   347  
   348      * CLI:
   349  
   350          ```
   351          esbuild --bundle --packages=external
   352          ```
   353  
   354      * JS:
   355  
   356          ```js
   357          esbuild.build({
   358            bundle: true,
   359            packages: 'external',
   360          })
   361          ```
   362  
   363      * Go:
   364  
   365          ```go
   366          api.Build(api.BuildOptions{
   367            Bundle:   true,
   368            Packages: api.PackagesExternal,
   369          })
   370          ```
   371  
   372      Doing `--external:./node_modules/*` is still possible and still has the same behavior, but is no longer recommended. I recommend that you use the new `packages` feature instead.
   373  
   374  * Fix some subtle bugs with tagged template literals
   375  
   376      This release fixes a bug where minification could incorrectly change the value of `this` within tagged template literal function calls:
   377  
   378      ```js
   379      // Original code
   380      function f(x) {
   381        let z = y.z
   382        return z``
   383      }
   384  
   385      // Old output (with --minify)
   386      function f(n){return y.z``}
   387  
   388      // New output (with --minify)
   389      function f(n){return(0,y.z)``}
   390      ```
   391  
   392      This release also fixes a bug where using optional chaining with `--target=es2019` or earlier could incorrectly change the value of `this` within tagged template literal function calls:
   393  
   394      ```js
   395      // Original code
   396      var obj = {
   397        foo: function() {
   398          console.log(this === obj);
   399        }
   400      };
   401      (obj?.foo)``;
   402  
   403      // Old output (with --target=es6)
   404      var obj = {
   405        foo: function() {
   406          console.log(this === obj);
   407        }
   408      };
   409      (obj == null ? void 0 : obj.foo)``;
   410  
   411      // New output (with --target=es6)
   412      var __freeze = Object.freeze;
   413      var __defProp = Object.defineProperty;
   414      var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) }));
   415      var _a;
   416      var obj = {
   417        foo: function() {
   418          console.log(this === obj);
   419        }
   420      };
   421      (obj == null ? void 0 : obj.foo).call(obj, _a || (_a = __template([""])));
   422      ```
   423  
   424  * Some slight minification improvements
   425  
   426      The following minification improvements were implemented:
   427  
   428      * `if (~a !== 0) throw x;` => `if (~a) throw x;`
   429      * `if ((a | b) !== 0) throw x;` => `if (a | b) throw x;`
   430      * `if ((a & b) !== 0) throw x;` => `if (a & b) throw x;`
   431      * `if ((a ^ b) !== 0) throw x;` => `if (a ^ b) throw x;`
   432      * `if ((a << b) !== 0) throw x;` => `if (a << b) throw x;`
   433      * `if ((a >> b) !== 0) throw x;` => `if (a >> b) throw x;`
   434      * `if ((a >>> b) !== 0) throw x;` => `if (a >>> b) throw x;`
   435      * `if (!!a || !!b) throw x;` => `if (a || b) throw x;`
   436      * `if (!!a && !!b) throw x;` => `if (a && b) throw x;`
   437      * `if (a ? !!b : !!c) throw x;` => `if (a ? b : c) throw x;`
   438  
   439  ## 0.16.4
   440  
   441  * Fix binary downloads from the `@esbuild/` scope for Deno ([#2729](https://github.com/evanw/esbuild/issues/2729))
   442  
   443      Version 0.16.0 of esbuild moved esbuild's binary executables into npm packages under the `@esbuild/` scope, which accidentally broke the binary downloader script for Deno. This release fixes this script so it should now be possible to use esbuild version 0.16.4+ with Deno.
   444  
   445  ## 0.16.3
   446  
   447  * Fix a hang with the JS API in certain cases ([#2727](https://github.com/evanw/esbuild/issues/2727))
   448  
   449      A change that was made in version 0.15.13 accidentally introduced a case when using esbuild's JS API could cause the node process to fail to exit. The change broke esbuild's watchdog timer, which detects if the parent process no longer exists and then automatically exits esbuild. This hang happened when you ran node as a child process with the `stderr` stream set to `pipe` instead of `inherit`, in the child process you call esbuild's JS API and pass `incremental: true` but do not call `dispose()` on the returned `rebuild` object, and then call `process.exit()`. In that case the parent node process was still waiting for the esbuild process that was created by the child node process to exit. The change made in version 0.15.13 was trying to avoid using Go's `sync.WaitGroup` API incorrectly because the API is not thread-safe. Instead of doing this, I have now reverted that change and implemented a thread-safe version of the `sync.WaitGroup` API for esbuild to use instead.
   450  
   451  ## 0.16.2
   452  
   453  * Fix `process.env.NODE_ENV` substitution when transforming ([#2718](https://github.com/evanw/esbuild/issues/2718))
   454  
   455      Version 0.16.0 introduced an unintentional regression that caused `process.env.NODE_ENV` to be automatically substituted with either `"development"` or `"production"` when using esbuild's `transform` API. This substitution is a necessary feature of esbuild's `build` API because the React framework crashes when you bundle it without doing this. But the `transform` API is typically used as part of a larger build pipeline so the benefit of esbuild doing this automatically is not as clear, and esbuild previously didn't do this.
   456  
   457      However, version 0.16.0 switched the default value of the `platform` setting for the `transform` API from `neutral` to `browser`, both to align it with esbuild's documentation (which says `browser` is the default value) and because escaping the `</script>` character sequence is now tied to the `browser` platform (see the release notes for version 0.16.0 for details). That accidentally enabled automatic substitution of `process.env.NODE_ENV` because esbuild always did that for code meant for the browser. To fix this regression, esbuild will now only automatically substitute `process.env.NODE_ENV` when using the `build` API.
   458  
   459  * Prevent `define` from substituting constants into assignment position ([#2719](https://github.com/evanw/esbuild/issues/2719))
   460  
   461      The `define` feature lets you replace certain expressions with constants. For example, you could use it to replace references to the global property reference `window.DEBUG` with `false` at compile time, which can then potentially help esbuild remove unused code from your bundle. It's similar to [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) in Webpack.
   462  
   463      However, if you write code such as `window.DEBUG = true` and then defined `window.DEBUG` to `false`, esbuild previously generated the output `false = true` which is a syntax error in JavaScript. This behavior is not typically a problem because it doesn't make sense to substitute `window.DEBUG` with a constant if its value changes at run-time (Webpack's `DefinePlugin` also generates `false = true` in this case). But it can be alarming to have esbuild generate code with a syntax error.
   464  
   465      So with this release, esbuild will no longer substitute `define` constants into assignment position to avoid generating code with a syntax error. Instead esbuild will generate a warning, which currently looks like this:
   466  
   467      ```
   468      ▲ [WARNING] Suspicious assignment to defined constant "window.DEBUG" [assign-to-define]
   469  
   470          example.js:1:0:
   471            1 │ window.DEBUG = true
   472              ╵ ~~~~~~~~~~~~
   473  
   474        The expression "window.DEBUG" has been configured to be replaced with a constant using the
   475        "define" feature. If this expression is supposed to be a compile-time constant, then it doesn't
   476        make sense to assign to it here. Or if this expression is supposed to change at run-time, this
   477        "define" substitution should be removed.
   478      ```
   479  
   480  * Fix a regression with `npm install --no-optional` ([#2720](https://github.com/evanw/esbuild/issues/2720))
   481  
   482      Normally when you install esbuild with `npm install`, npm itself is the tool that downloads the correct binary executable for the current platform. This happens because of how esbuild's primary package uses npm's `optionalDependencies` feature. However, if you deliberately disable this with `npm install --no-optional` then esbuild's install script will attempt to repair the installation by manually downloading and extracting the binary executable from the package that was supposed to be installed.
   483  
   484      The change in version 0.16.0 to move esbuild's nested packages into the `@esbuild/` scope unintentionally broke this logic because of how npm's URL structure is different for scoped packages vs. normal packages. It was actually already broken for a few platforms earlier because esbuild already had packages for some platforms in the `@esbuild/` scope, but I didn't discover this then because esbuild's integration tests aren't run on all platforms. Anyway, this release contains some changes to the install script that should hopefully get this scenario working again.
   485  
   486  ## 0.16.1
   487  
   488  This is a hotfix for the previous release.
   489  
   490  * Re-allow importing JSON with the `copy` loader using an import assertion
   491  
   492      The previous release made it so when `assert { type: 'json' }` is present on an import statement, esbuild validated that the `json` loader was used. This is what an import assertion is supposed to do. However, I forgot about the relatively new `copy` loader, which sort of behaves as if the import path was marked as external (and thus not loaded at all) except that the file is copied to the output directory and the import path is rewritten to point to the copy. In this case whatever JavaScript runtime ends up running the code is the one to evaluate the import assertion. So esbuild should really allow this case as well. With this release, esbuild now allows both the `json` and `copy` loaders when an `assert { type: 'json' }` import assertion is present.
   493  
   494  ## 0.16.0
   495  
   496  **This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.15.0` or `~0.15.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.
   497  
   498  * Move all binary executable packages to the `@esbuild/` scope
   499  
   500      Binary package executables for esbuild are published as individual packages separate from the main `esbuild` package so you only have to download the relevant one for the current platform when you install esbuild. This release moves all of these packages under the `@esbuild/` scope to avoid collisions with 3rd-party packages. It also changes them to a consistent naming scheme that uses the `os` and `cpu` names from node.
   501  
   502      The package name changes are as follows:
   503  
   504      * `@esbuild/linux-loong64` => `@esbuild/linux-loong64` (no change)
   505      * `esbuild-android-64` => `@esbuild/android-x64`
   506      * `esbuild-android-arm64` => `@esbuild/android-arm64`
   507      * `esbuild-darwin-64` => `@esbuild/darwin-x64`
   508      * `esbuild-darwin-arm64` => `@esbuild/darwin-arm64`
   509      * `esbuild-freebsd-64` => `@esbuild/freebsd-x64`
   510      * `esbuild-freebsd-arm64` => `@esbuild/freebsd-arm64`
   511      * `esbuild-linux-32` => `@esbuild/linux-ia32`
   512      * `esbuild-linux-64` => `@esbuild/linux-x64`
   513      * `esbuild-linux-arm` => `@esbuild/linux-arm`
   514      * `esbuild-linux-arm64` => `@esbuild/linux-arm64`
   515      * `esbuild-linux-mips64le` => `@esbuild/linux-mips64el`
   516      * `esbuild-linux-ppc64le` => `@esbuild/linux-ppc64`
   517      * `esbuild-linux-riscv64` => `@esbuild/linux-riscv64`
   518      * `esbuild-linux-s390x` => `@esbuild/linux-s390x`
   519      * `esbuild-netbsd-64` => `@esbuild/netbsd-x64`
   520      * `esbuild-openbsd-64` => `@esbuild/openbsd-x64`
   521      * `esbuild-sunos-64` => `@esbuild/sunos-x64`
   522      * `esbuild-wasm` => `esbuild-wasm` (no change)
   523      * `esbuild-windows-32` => `@esbuild/win32-ia32`
   524      * `esbuild-windows-64` => `@esbuild/win32-x64`
   525      * `esbuild-windows-arm64` => `@esbuild/win32-arm64`
   526      * `esbuild` => `esbuild` (no change)
   527  
   528      Normal usage of the `esbuild` and `esbuild-wasm` packages should not be affected. These name changes should only affect tools that hard-coded the individual binary executable package names into custom esbuild downloader scripts.
   529  
   530      This change was not made with performance in mind. But as a bonus, installing esbuild with npm may potentially happen faster now. This is because npm's package installation protocol is inefficient: it always downloads metadata for all past versions of each package even when it only needs metadata about a single version. This makes npm package downloads O(n) in the number of published versions, which penalizes packages like esbuild that are updated regularly. Since most of esbuild's package names have now changed, npm will now need to download much less data when installing esbuild (8.72mb of package manifests before this change → 0.06mb of package manifests after this change). However, this is only a temporary improvement. Installing esbuild will gradually get slower again as further versions of esbuild are published.
   531  
   532  * Publish a shell script that downloads esbuild directly
   533  
   534      In addition to all of the existing ways to install esbuild, you can now also download esbuild directly like this:
   535  
   536      ```sh
   537      curl -fsSL https://esbuild.github.io/dl/latest | sh
   538      ```
   539  
   540      This runs a small shell script that downloads the latest `esbuild` binary executable to the current directory. This can be convenient on systems that don't have `npm` installed or when you just want to get a copy of esbuild quickly without any extra steps. If you want a specific version of esbuild (starting with this version onward), you can provide that version in the URL instead of `latest`:
   541  
   542      ```sh
   543      curl -fsSL https://esbuild.github.io/dl/v0.16.0 | sh
   544      ```
   545  
   546      Note that the download script needs to be able to access registry.npmjs.org to be able to complete the download. This download script doesn't yet support all of the platforms that esbuild supports because I lack the necessary testing environments. If the download script doesn't work for you because you're on an unsupported platform, please file an issue on the esbuild repo so we can add support for it.
   547  
   548  * Fix some parameter names for the Go API
   549  
   550      This release changes some parameter names for the Go API to be consistent with the JavaScript and CLI APIs:
   551  
   552      * `OutExtensions` => `OutExtension`
   553      * `JSXMode` => `JSX`
   554  
   555  * Add additional validation of API parameters
   556  
   557      The JavaScript API now does some additional validation of API parameters to catch incorrect uses of esbuild's API. The biggest impact of this is likely that esbuild now strictly only accepts strings with the `define` parameter. This would already have been a type error with esbuild's TypeScript type definitions, but it was previously not enforced for people using esbuild's API JavaScript without TypeScript.
   558  
   559      The `define` parameter appears at first glance to take a JSON object if you aren't paying close attention, but this actually isn't true. Values for `define` are instead strings of JavaScript code. This means you have to use `define: { foo: '"bar"' }` to replace `foo` with the string `"bar"`. Using `define: { foo: 'bar' }` actually replaces `foo` with the identifier `bar`. Previously esbuild allowed you to pass `define: { foo: false }` and `false` was automatically converted into a string, which made it more confusing to understand what `define` actually represents. Starting with this release, passing non-string values such as with `define: { foo: false }` will no longer be allowed. You will now have to write `define: { foo: 'false' }` instead.
   560  
   561  * Generate shorter data URLs if possible ([#1843](https://github.com/evanw/esbuild/issues/1843))
   562  
   563      Loading a file with esbuild's `dataurl` loader generates a JavaScript module with a [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) for that file in a string as a single default export. Previously the data URLs generated by esbuild all used [base64 encoding](https://en.wikipedia.org/wiki/Base64). However, this is unnecessarily long for most textual data (e.g. SVG images). So with this release, esbuild's `dataurl` loader will now use percent encoding instead of base64 encoding if the result will be shorter. This can result in ~25% smaller data URLs for large SVGs. If you want the old behavior, you can use the `base64` loader instead and then construct the data URL yourself.
   564  
   565  * Avoid marking entry points as external ([#2382](https://github.com/evanw/esbuild/issues/2382))
   566  
   567      Previously you couldn't specify `--external:*` to mark all import paths as external because that also ended up making the entry point itself external, which caused the build to fail. With this release, esbuild's `external` API parameter no longer applies to entry points so using `--external:*` is now possible.
   568  
   569      One additional consequence of this change is that the `kind` parameter is now required when calling the `resolve()` function in esbuild's plugin API. Previously the `kind` parameter defaulted to `entry-point`, but that no longer interacts with `external` so it didn't seem wise for this to continue to be the default. You now have to specify `kind` so that the path resolution mode is explicit.
   570  
   571  * Disallow non-`default` imports when `assert { type: 'json' }` is present
   572  
   573      There is now standard behavior for importing a JSON file into an ES module using an `import` statement. However, it requires you to place the `assert { type: 'json' }` import assertion after the import path. This import assertion tells the JavaScript runtime to throw an error if the import does not end up resolving to a JSON file. On the web, the type of a file is determined by the `Content-Type` HTTP header instead of by the file extension. The import assertion prevents security problems on the web where a `.json` file may actually resolve to a JavaScript file containing malicious code, which is likely not expected for an import that is supposed to only contain pure side-effect free data.
   574  
   575      By default, esbuild uses the file extension to determine the type of a file, so this import assertion is unnecessary with esbuild. However, esbuild's JSON import feature has a non-standard extension that allows you to import top-level properties of the JSON object as named imports. For example, esbuild lets you do this:
   576  
   577      ```js
   578      import { version } from './package.json'
   579      ```
   580  
   581      This is useful for tree-shaking when bundling because it means esbuild will only include the the `version` field of `package.json` in your bundle. This is non-standard behavior though and doesn't match the behavior of what happens when you import JSON in a real JavaScript runtime (after adding `assert { type: 'json' }`). In a real JavaScript runtime the only thing you can import is the `default` import. So with this release, esbuild will now prevent you from importing non-`default` import names if `assert { type: 'json' }` is present. This ensures that code containing `assert { type: 'json' }` isn't relying on non-standard behavior that won't work everywhere. So the following code is now an error with esbuild when bundling:
   582  
   583      ```js
   584      import { version } from './package.json' assert { type: 'json' }
   585      ```
   586  
   587      In addition, adding `assert { type: 'json' }` to an import statement now means esbuild will generate an error if the loader for the file is anything other than `json`, which is required by the import assertion specification.
   588  
   589  * Provide a way to disable automatic escaping of `</script>` ([#2649](https://github.com/evanw/esbuild/issues/2649))
   590  
   591      If you inject esbuild's output into a script tag in an HTML file, code containing the literal characters `</script>` will cause the tag to be ended early which will break the code:
   592  
   593      ```html
   594      <script>
   595        console.log("</script>");
   596      </script>
   597      ```
   598  
   599      To avoid this, esbuild automatically escapes these strings in generated JavaScript files (e.g. `"</script>"` becomes `"<\/script>"` instead). This also applies to `</style>` in generated CSS files. Previously this always happened and there wasn't a way to turn this off.
   600  
   601      With this release, esbuild will now only do this if the `platform` setting is set to `browser` (the default value). Setting `platform` to `node` or `neutral` will disable this behavior. This behavior can also now be disabled with `--supported:inline-script=false` (for JS) and `--supported:inline-style=false` (for CSS).
   602  
   603  * Throw an early error if decoded UTF-8 text isn't a `Uint8Array` ([#2532](https://github.com/evanw/esbuild/issues/2532))
   604  
   605      If you run esbuild's JavaScript API in a broken JavaScript environment where `new TextEncoder().encode("") instanceof Uint8Array` is false, then esbuild's API will fail with a confusing serialization error message that makes it seem like esbuild has a bug even though the real problem is that the JavaScript environment itself is broken. This can happen when using the test framework called [Jest](https://jestjs.io/). With this release, esbuild's API will now throw earlier when it detects that the environment is unable to encode UTF-8 text correctly with an error message that makes it more clear that this is not a problem with esbuild.
   606  
   607  * Change the default "legal comment" behavior
   608  
   609      The legal comments feature automatically gathers comments containing `@license` or `@preserve` and puts the comments somewhere (either in the generated code or in a separate file). People sometimes want this to happen so that the their dependencies' software licenses are retained in the generated output code. By default esbuild puts these comments at the end of the file when bundling. However, people sometimes find this confusing because these comments can be very generic and may not mention which library they come from. So with this release, esbuild will now discard legal comments by default. You now have to opt-in to preserving them if you want this behavior.
   610  
   611  * Enable the `module` condition by default ([#2417](https://github.com/evanw/esbuild/issues/2417))
   612  
   613      Package authors want to be able to use the new [`exports`](https://nodejs.org/api/packages.html#conditional-exports) field in `package.json` to provide tree-shakable ESM code for ESM-aware bundlers while simultaneously providing fallback CommonJS code for other cases.
   614  
   615      Node's proposed way to do this involves using the `import` and `require` export conditions so that you get the ESM code if you use an import statement and the CommonJS code if you use a require call. However, this has a major drawback: if some code in the bundle uses an import statement and other code in the bundle uses a require call, then you'll get two copies of the same package in the bundle. This is known as the [dual package hazard](https://nodejs.org/api/packages.html#dual-package-hazard) and can lead to bloated bundles or even worse to subtle logic bugs.
   616  
   617      Webpack supports an alternate solution: an export condition called `module` that takes effect regardless of whether the package was imported using an import statement or a require call. This works because bundlers such as Webpack support importing a ESM using a require call (something node doesn't support). You could already do this with esbuild using `--conditions=module` but you previously had to explicitly enable this. Package authors are concerned that esbuild users won't know to do this and will get suboptimal output with their package, so they have requested for esbuild to do this automatically.
   618  
   619      So with this release, esbuild will now automatically add the `module` condition when there aren't any custom `conditions` already configured. You can disable this with `--conditions=` or `conditions: []` (i.e. explicitly clearing all custom conditions).
   620  
   621  * Rename the `master` branch to `main`
   622  
   623      The primary branch for this repository was previously called `master` but is now called `main`. This change mirrors a similar change in many other projects.
   624  
   625  * Remove esbuild's `_exit(0)` hack for WebAssembly ([#714](https://github.com/evanw/esbuild/issues/714))
   626  
   627      Node had an unfortunate bug where the node process is unnecessarily kept open while a WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616. This means cases where running `esbuild` should take a few milliseconds can end up taking many seconds instead.
   628  
   629      The workaround was to force node to exit by ending the process early. This was done by esbuild in one of two ways depending on the exit code. For non-zero exit codes (i.e. when there is a build error), the `esbuild` command could just call `process.kill(process.pid)` to avoid the hang. But for zero exit codes, esbuild had to load a N-API native node extension that calls the operating system's `exit(0)` function.
   630  
   631      However, this problem has essentially been fixed in node starting with version 18.3.0. So I have removed this hack from esbuild. If you are using an earlier version of node with `esbuild-wasm` and you don't want the `esbuild` command to hang for a while when exiting, you can upgrade to node 18.3.0 or higher to remove the hang.
   632  
   633      The fix came from a V8 upgrade: [this commit](https://github.com/v8/v8/commit/bfe12807c14c91714c7db1485e6b265439375e16) enabled [dynamic tiering for WebAssembly](https://v8.dev/blog/wasm-dynamic-tiering) by default for all projects that use V8's WebAssembly implementation. Previously all functions in the WebAssembly module were optimized in a single batch job but with dynamic tiering, V8 now optimizes individual WebAssembly functions as needed. This avoids unnecessary WebAssembly compilation which allows node to exit on time.
   634  
   635  ## 0.15.18
   636  
   637  * Performance improvements for both JS and CSS
   638  
   639      This release brings noticeable performance improvements for JS parsing and for CSS parsing and printing. Here's an example benchmark for using esbuild to pretty-print a single large minified CSS file and JS file:
   640  
   641      | Test case      | Previous release | This release       |
   642      |----------------|------------------|--------------------|
   643      | 4.8mb CSS file | 19ms             | 11ms (1.7x faster) |
   644      | 5.8mb JS file  | 36ms             | 32ms (1.1x faster) |
   645  
   646      The performance improvements were very straightforward:
   647  
   648      * Identifiers were being scanned using a generic character advancement function instead of using custom inline code. Advancing past each character involved UTF-8 decoding as well as updating multiple member variables. This was sped up using loop that skips UTF-8 decoding entirely and that only updates member variables once at the end. This is faster because identifiers are plain ASCII in the vast majority of cases, so Unicode decoding is almost always unnecessary.
   649  
   650      * CSS identifiers and CSS strings were still being printed one character at a time. Apparently I forgot to move this part of esbuild's CSS infrastructure beyond the proof-of-concept stage. These were both very obvious in the profiler, so I think maybe I have just never profiled esbuild's CSS printing before?
   651  
   652      * There was unnecessary work being done that was related to source maps when source map output was disabled. I likely haven't observed this before because esbuild's benchmarks always have source maps enabled. This work is now disabled when it's not going to be used.
   653  
   654      I definitely should have caught these performance issues earlier. Better late than never I suppose.
   655  
   656  ## 0.15.17
   657  
   658  * Search for missing source map code on the file system ([#2711](https://github.com/evanw/esbuild/issues/2711))
   659  
   660      [Source maps](https://sourcemaps.info/spec.html) are JSON files that map from compiled code back to the original code. They provide the original source code using two arrays: `sources` (required) and `sourcesContent` (optional). When bundling is enabled, esbuild is able to bundle code with source maps that was compiled by other tools (e.g. with Webpack) and emit source maps that map all the way back to the original code (e.g. before Webpack compiled it).
   661  
   662      Previously if the input source maps omitted the optional `sourcesContent` array, esbuild would use `null` for the source content in the source map that it generates (since the source content isn't available). However, sometimes the original source code is actually still present on the file system. With this release, esbuild will now try to find the original source code using the path in the `sources` array and will use that instead of `null` if it was found.
   663  
   664  * Fix parsing bug with TypeScript `infer` and `extends` ([#2712](https://github.com/evanw/esbuild/issues/2712))
   665  
   666      This release fixes a bug where esbuild incorrectly failed to parse valid TypeScript code that nests `extends` inside `infer` inside `extends`, such as in the example below:
   667  
   668      ```ts
   669      type A<T> = {};
   670      type B = {} extends infer T extends {} ? A<T> : never;
   671      ```
   672  
   673      TypeScript code that does this should now be parsed correctly.
   674  
   675  * Use `WebAssembly.instantiateStreaming` if available ([#1036](https://github.com/evanw/esbuild/pull/1036), [#1900](https://github.com/evanw/esbuild/pull/1900))
   676  
   677      Currently the WebAssembly version of esbuild uses `fetch` to download `esbuild.wasm` and then `WebAssembly.instantiate` to compile it. There is a newer API called `WebAssembly.instantiateStreaming` that both downloads and compiles at the same time, which can be a performance improvement if both downloading and compiling are slow. With this release, esbuild now attempts to use `WebAssembly.instantiateStreaming` and falls back to the original approach if that fails.
   678  
   679      The implementation for this builds on a PR by [@lbwa](https://github.com/lbwa).
   680  
   681  * Preserve Webpack comments inside constructor calls ([#2439](https://github.com/evanw/esbuild/issues/2439))
   682  
   683      This improves the use of esbuild as a faster TypeScript-to-JavaScript frontend for Webpack, which has special [magic comments](https://webpack.js.org/api/module-methods/#magic-comments) inside `new Worker()` expressions that affect Webpack's behavior.
   684  
   685  ## 0.15.16
   686  
   687  * Add a package alias feature ([#2191](https://github.com/evanw/esbuild/issues/2191))
   688  
   689      With this release, you can now easily substitute one package for another at build time with the new `alias` feature. For example, `--alias:oldpkg=newpkg` replaces all imports of `oldpkg` with `newpkg`. One use case for this is easily replacing a node-only package with a browser-friendly package in 3rd-party code that you don't control. These new substitutions happen first before all of esbuild's existing path resolution logic.
   690  
   691      Note that when an import path is substituted using an alias, the resulting import path is resolved in the working directory instead of in the directory containing the source file with the import path. If needed, the working directory can be set with the `cd` command when using the CLI or with the `absWorkingDir` setting when using the JS or Go APIs.
   692  
   693  * Fix crash when pretty-printing minified JSX with object spread of object literal with computed property ([#2697](https://github.com/evanw/esbuild/issues/2697))
   694  
   695      JSX elements are translated to JavaScript function calls and JSX element attributes are translated to properties on a JavaScript object literal. These properties are always either strings (e.g. in `<x y />`, `y` is a string) or an object spread (e.g. in `<x {...y} />`, `y` is an object spread) because JSX doesn't provide syntax for directly passing a computed property as a JSX attribute. However, esbuild's minifier has a rule that tries to inline object spread with an inline object literal in JavaScript. For example, `x = { ...{ y } }` is minified to `x={y}` when minification is enabled. This means that there is a way to generate a non-string non-spread JSX attribute in esbuild's internal representation. One example is with `<x {...{ [y]: z }} />`. When minification is enabled, esbuild's internal representation of this is something like `<x [y]={z} />` due to object spread inlining, which is not valid JSX syntax. If this internal representation is then pretty-printed as JSX using `--minify --jsx=preserve`, esbuild previously crashed when trying to print this invalid syntax. With this release, esbuild will now print `<x {...{[y]:z}}/>` in this scenario instead of crashing.
   696  
   697  ## 0.15.15
   698  
   699  * Remove duplicate CSS rules across files ([#2688](https://github.com/evanw/esbuild/issues/2688))
   700  
   701      When two or more CSS rules are exactly the same (even if they are not adjacent), all but the last one can safely be removed:
   702  
   703      ```css
   704      /* Before */
   705      a { color: red; }
   706      span { font-weight: bold; }
   707      a { color: red; }
   708  
   709      /* After */
   710      span { font-weight: bold; }
   711      a { color: red; }
   712      ```
   713  
   714      Previously esbuild only did this transformation within a single source file. But with this release, esbuild will now do this transformation across source files, which may lead to smaller CSS output if the same rules are repeated across multiple CSS source files in the same bundle. This transformation is only enabled when minifying (specifically when syntax minification is enabled).
   715  
   716  * Add `deno` as a valid value for `target` ([#2686](https://github.com/evanw/esbuild/issues/2686))
   717  
   718      The `target` setting in esbuild allows you to enable or disable JavaScript syntax features for a given version of a set of target JavaScript VMs. Previously [Deno](https://deno.land/) was not one of the JavaScript VMs that esbuild supported with `target`, but it will now be supported starting from this release. For example, versions of Deno older than v1.2 don't support the new `||=` operator, so adding e.g. `--target=deno1.0` to esbuild now lets you tell esbuild to transpile `||=` to older JavaScript.
   719  
   720  * Fix the `esbuild-wasm` package in Node v19 ([#2683](https://github.com/evanw/esbuild/issues/2683))
   721  
   722      A recent change to Node v19 added a non-writable `crypto` property to the global object: https://github.com/nodejs/node/pull/44897. This conflicts with Go's WebAssembly shim code, which overwrites the global `crypto` property. As a result, all Go-based WebAssembly code that uses the built-in shim (including esbuild) is now broken on Node v19. This release of esbuild fixes the issue by reconfiguring the global `crypto` property to be writable before invoking Go's WebAssembly shim code.
   723  
   724  * Fix CSS dimension printing exponent confusion edge case ([#2677](https://github.com/evanw/esbuild/issues/2677))
   725  
   726      In CSS, a dimension token has a numeric "value" part and an identifier "unit" part. For example, the dimension token `32px` has a value of `32` and a unit of `px`. The unit can be any valid CSS identifier. The value can be any number in floating-point format including an optional exponent (e.g. `-3.14e-0` has an exponent of `e-0`). The full details of this syntax are here: https://www.w3.org/TR/css-syntax-3/.
   727  
   728      To maintain the integrity of the dimension token through the printing process, esbuild must handle the edge case where the unit looks like an exponent. One such case is the dimension `1e\32` which has the value `1` and the unit `e2`. It would be bad if this dimension token was printed such that a CSS parser would parse it as a number token with the value `1e2` instead of a dimension token. The way esbuild currently does this is to escape the leading `e` in the dimension unit, so esbuild would parse `1e\32` but print `1\65 2` (both `1e\32` and `1\65 2` represent a dimension token with a value of `1` and a unit of `e2`).
   729  
   730      However, there is an even narrower edge case regarding this edge case. If the value part of the dimension token itself has an `e`, then it's not necessary to escape the `e` in the dimension unit because a CSS parser won't confuse the unit with the exponent even though it looks like one (since a number can only have at most one exponent). This came up because the grammar for the CSS `unicode-range` property uses a hack that lets you specify a hexadecimal range without quotes even though CSS has no token for a hexadecimal range. The hack is to allow the hexadecimal range to be parsed as a dimension token and optionally also a number token. Here is the grammar for `unicode-range`:
   731  
   732      ```
   733      unicode-range =
   734        <urange>#
   735  
   736      <urange> =
   737        u '+' <ident-token> '?'*            |
   738        u <dimension-token> '?'*            |
   739        u <number-token> '?'*               |
   740        u <number-token> <dimension-token>  |
   741        u <number-token> <number-token>     |
   742        u '+' '?'+
   743      ```
   744  
   745      and here is an example `unicode-range` declaration that was problematic for esbuild:
   746  
   747      ```css
   748      @font-face {
   749        unicode-range: U+0e2e-0e2f;
   750      }
   751      ```
   752  
   753      This is parsed as a dimension with a value of `+0e2` and a unit of `e-0e2f`. This was problematic for esbuild because the unit starts with `e-0` which could be confused with an exponent when appended after a number, so esbuild was escaping the `e` character in the unit. However, this escaping is unnecessary because in this case the dimension value already has an exponent in it. With this release, esbuild will no longer unnecessarily escape the `e` in the dimension unit in these cases, which should fix the printing of `unicode-range` declarations.
   754  
   755      An aside: You may be wondering why esbuild is trying to escape the `e` at all and why it doesn't just pass through the original source code unmodified. The reason why esbuild does this is that, for robustness, esbuild's AST generally tries to omit semantically-unrelated information and esbuild's code printers always try to preserve the semantics of the underlying AST. That way the rest of esbuild's internals can just deal with semantics instead of presentation. They don't have to think about how the AST will be printed when changing the AST. This is the same reason that esbuild's JavaScript AST doesn't have a "parentheses" node (e.g. `a * (b + c)` is represented by the AST `multiply(a, add(b, c))` instead of `multiply(a, parentheses(add(b, c)))`). Instead, the printer automatically inserts parentheses as necessary to maintain the semantics of the AST, which means all of the optimizations that run over the AST don't have to worry about keeping the parentheses up to date. Similarly, the CSS AST for the dimension token stores the actual unit and the printer makes sure the unit is properly escaped depending on what value it's placed after. All of the other code operating on CSS ASTs doesn't have to worry about parsing escapes to compare units or about keeping escapes up to date when the AST is modified. Hopefully that makes sense.
   756  
   757  * Attempt to avoid creating the `node_modules/.cache` directory for people that use Yarn 2+ in Plug'n'Play mode ([#2685](https://github.com/evanw/esbuild/issues/2685))
   758  
   759      When Yarn's PnP mode is enabled, packages installed by Yarn may or may not be put inside `.zip` files. The specific heuristics for when this happens change over time in between Yarn versions. This is problematic for esbuild because esbuild's JavaScript package needs to execute a binary file inside the package. Yarn makes extensive modifications to Node's file system APIs at run time to pretend that `.zip` files are normal directories and to make it hard to tell whether a file is real or not (since in theory it doesn't matter). But they haven't modified Node's `child_process.execFileSync` API so attempting to execute a file inside a zip file fails. To get around this, esbuild previously used Node's file system APIs to copy the binary executable to another location before invoking `execFileSync`. Under the hood this caused Yarn to extract the file from the zip file into a real file that can then be run.
   760  
   761      However, esbuild copied its executable into `node_modules/.cache/esbuild`. This is the [official recommendation from the Yarn team](https://yarnpkg.com/advanced/rulebook/#packages-should-never-write-inside-their-own-folder-outside-of-postinstall) for where packages are supposed to put these types of files when Yarn PnP is being used. However, users of Yarn PnP with esbuild find this really annoying because they don't like looking at the `node_modules` directory. With this release, esbuild now sets `"preferUnplugged": true` in its `package.json` files, which tells newer versions of Yarn to not put esbuild's packages in a zip file. There may exist older versions of Yarn that don't support `preferUnplugged`. In that case esbuild should still copy the executable to a cache directory, so it should still run (hopefully, since I haven't tested this myself). Note that esbuild setting `"preferUnplugged": true` may have the side effect of esbuild taking up more space on the file system in the event that multiple platforms are installed simultaneously, or that you're using an older version of Yarn that always installs packages for all platforms. In that case you may want to update to a newer version of Yarn since Yarn has recently changed to only install packages for the current platform.
   762  
   763  ## 0.15.14
   764  
   765  * Fix parsing of TypeScript `infer` inside a conditional `extends` ([#2675](https://github.com/evanw/esbuild/issues/2675))
   766  
   767      Unlike JavaScript, parsing TypeScript sometimes requires backtracking. The `infer A` type operator can take an optional constraint of the form `infer A extends B`. However, this syntax conflicts with the similar conditional type operator `A extends B ? C : D` in cases where the syntax is combined, such as `infer A extends B ? C : D`. This is supposed to be parsed as `(infer A) extends B ? C : D`. Previously esbuild incorrectly parsed this as `(infer A extends B) ? C : D` instead, which is a parse error since the `?:` conditional operator requires the `extends` keyword as part of the conditional type. TypeScript disambiguates by speculatively parsing the `extends` after the `infer`, but backtracking if a `?` token is encountered afterward. With this release, esbuild should now do the same thing, so esbuild should now correctly parse these types. Here's a real-world example of such a type:
   768  
   769      ```ts
   770      type Normalized<T> = T extends Array<infer A extends object ? infer A : never>
   771        ? Dictionary<Normalized<A>>
   772        : {
   773            [P in keyof T]: T[P] extends Array<infer A extends object ? infer A : never>
   774              ? Dictionary<Normalized<A>>
   775              : Normalized<T[P]>
   776          }
   777      ```
   778  
   779  * Avoid unnecessary watch mode rebuilds when debug logging is enabled ([#2661](https://github.com/evanw/esbuild/issues/2661))
   780  
   781      When debug-level logs are enabled (such as with `--log-level=debug`), esbuild's path resolution subsystem generates debug log messages that say something like "Read 20 entries for directory /home/user" to help you debug what esbuild's path resolution is doing. This caused esbuild's watch mode subsystem to add a dependency on the full list of entries in that directory since if that changes, the generated log message would also have to be updated. However, meant that on systems where a parent directory undergoes constant directory entry churn, esbuild's watch mode would continue to rebuild if `--log-level=debug` was passed.
   782  
   783      With this release, these debug log messages are now generated by "peeking" at the file system state while bypassing esbuild's watch mode dependency tracking. So now watch mode doesn't consider the count of directory entries in these debug log messages to be a part of the build that needs to be kept up to date when the file system state changes.
   784  
   785  ## 0.15.13
   786  
   787  * Add support for the TypeScript 4.9 `satisfies` operator ([#2509](https://github.com/evanw/esbuild/pull/2509))
   788  
   789      TypeScript 4.9 introduces a new operator called `satisfies` that lets you check that a given value satisfies a less specific type without casting it to that less specific type and without generating any additional code at run-time. It looks like this:
   790  
   791      ```ts
   792      const value = { foo: 1, bar: false } satisfies Record<string, number | boolean>
   793      console.log(value.foo.toFixed(1)) // TypeScript knows that "foo" is a number here
   794      ```
   795  
   796      Before this existed, you could use a cast with `as` to check that a value satisfies a less specific type, but that removes any additional knowledge that TypeScript has about that specific value:
   797  
   798      ```ts
   799      const value = { foo: 1, bar: false } as Record<string, number | boolean>
   800      console.log(value.foo.toFixed(1)) // TypeScript no longer knows that "foo" is a number
   801      ```
   802  
   803      You can read more about this feature in [TypeScript's blog post for 4.9](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-rc/#the-satisfies-operator) as well as [the associated TypeScript issue for this feature](https://github.com/microsoft/TypeScript/issues/47920).
   804  
   805      This feature was implemented in esbuild by [@magic-akari](https://github.com/magic-akari).
   806  
   807  * Fix watch mode constantly rebuilding if the parent directory is inaccessible ([#2640](https://github.com/evanw/esbuild/issues/2640))
   808  
   809      Android is unusual in that it has an inaccessible directory in the path to the root, which esbuild was not originally built to handle. To handle cases like this, the path resolution layer in esbuild has a hack where it treats inaccessible directories as empty. However, esbuild's watch implementation currently triggers a rebuild if a directory previously encountered an error but the directory now exists. The assumption is that the previous error was caused by the directory not existing. Although that's usually the case, it's not the case for this particular parent directory on Android. Instead the error is that the directory previously existed but was inaccessible.
   810  
   811      This discrepancy between esbuild's path resolution layer and its watch mode was causing watch mode to rebuild continuously on Android. With this release, esbuild's watch mode instead checks for an error status change in the `readdir` file system call, so watch mode should no longer rebuild continuously on Android.
   812  
   813  * Apply a fix for a rare deadlock with the JavaScript API ([#1842](https://github.com/evanw/esbuild/issues/1842), [#2485](https://github.com/evanw/esbuild/issues/2485))
   814  
   815      There have been reports of esbuild sometimes exiting with an "all goroutines are asleep" deadlock message from the Go language runtime. This issue hasn't made much progress until recently, where a possible cause was discovered (thanks to [@jfirebaugh](https://github.com/jfirebaugh) for the investigation). This release contains a possible fix for that possible cause, so this deadlock may have been fixed. The fix cannot be easily verified because the deadlock is non-deterministic and rare. If this was indeed the cause, then this issue only affected the JavaScript API in situations where esbuild was already in the process of exiting.
   816  
   817      In detail: The underlying cause is that Go's [`sync.WaitGroup`](https://pkg.go.dev/sync#WaitGroup) API for waiting for a set of goroutines to finish is not fully thread-safe. Specifically it's not safe to call `Add()` concurrently with `Wait()` when the wait group counter is zero due to a data race. This situation could come up with esbuild's JavaScript API when the host JavaScript process closes the child process's stdin and the child process (with no active tasks) calls `Wait()` to check that there are no active tasks, at the same time as esbuild's watchdog timer calls `Add()` to add an active task (that pings the host to see if it's still there). The fix in this release is to avoid calling `Add()` once we learn that stdin has been closed but before we call `Wait()`.
   818  
   819  ## 0.15.12
   820  
   821  * Fix minifier correctness bug with single-use substitutions ([#2619](https://github.com/evanw/esbuild/issues/2619))
   822  
   823      When minification is enabled, esbuild will attempt to eliminate variables that are only used once in certain cases. For example, esbuild minifies this code:
   824  
   825      ```js
   826      function getEmailForUser(name) {
   827        let users = db.table('users');
   828        let user = users.find({ name });
   829        let email = user?.get('email');
   830        return email;
   831      }
   832      ```
   833  
   834      into this code:
   835  
   836      ```js
   837      function getEmailForUser(e){return db.table("users").find({name:e})?.get("email")}
   838      ```
   839  
   840      However, this transformation had a bug where esbuild did not correctly consider the "read" part of binary read-modify-write assignment operators. For example, it's incorrect to minify the following code into `bar += fn()` because the call to `fn()` might modify `bar`:
   841  
   842      ```js
   843      const foo = fn();
   844      bar += foo;
   845      ```
   846  
   847      In addition to fixing this correctness bug, this release also improves esbuild's output in the case where all values being skipped over are primitives:
   848  
   849      ```js
   850      function toneMapLuminance(r, g, b) {
   851        let hdr = luminance(r, g, b)
   852        let decay = 1 / (1 + hdr)
   853        return 1 - decay
   854      }
   855      ```
   856  
   857      Previous releases of esbuild didn't substitute these single-use variables here, but esbuild will now minify this to the following code starting with this release:
   858  
   859      ```js
   860      function toneMapLuminance(e,n,a){return 1-1/(1+luminance(e,n,a))}
   861      ```
   862  
   863  ## 0.15.11
   864  
   865  * Fix various edge cases regarding template tags and `this` ([#2610](https://github.com/evanw/esbuild/issues/2610))
   866  
   867      This release fixes some bugs where the value of `this` wasn't correctly preserved when evaluating template tags in a few edge cases. These edge cases are listed below:
   868  
   869      ```js
   870      async function test() {
   871        class Foo { foo() { return this } }
   872        class Bar extends Foo {
   873          a = async () => super.foo``
   874          b = async () => super['foo']``
   875          c = async (foo) => super[foo]``
   876        }
   877        function foo() { return this }
   878        const obj = { foo }
   879        const bar = new Bar
   880        console.log(
   881          (await bar.a()) === bar,
   882          (await bar.b()) === bar,
   883          (await bar.c('foo')) === bar,
   884          { foo }.foo``.foo === foo,
   885          (true && obj.foo)`` !== obj,
   886          (false || obj.foo)`` !== obj,
   887          (null ?? obj.foo)`` !== obj,
   888        )
   889      }
   890      test()
   891      ```
   892  
   893      Each edge case in the code above previously incorrectly printed `false` when run through esbuild with `--minify --target=es6` but now correctly prints `true`. These edge cases are unlikely to have affected real-world code.
   894  
   895  ## 0.15.10
   896  
   897  * Add support for node's "pattern trailers" syntax ([#2569](https://github.com/evanw/esbuild/issues/2569))
   898  
   899      After esbuild implemented node's `exports` feature in `package.json`, node changed the feature to also allow text after `*` wildcards in patterns. Previously the `*` was required to be at the end of the pattern. It lets you do something like this:
   900  
   901      ```json
   902      {
   903        "exports": {
   904          "./features/*": "./features/*.js",
   905          "./features/*.js": "./features/*.js"
   906        }
   907      }
   908      ```
   909  
   910      With this release, esbuild now supports these types of patterns too.
   911  
   912  * Fix subpath imports with Yarn PnP ([#2545](https://github.com/evanw/esbuild/issues/2545))
   913  
   914      Node has a little-used feature called [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) which are package-internal imports that start with `#` and that go through the `imports` map in `package.json`. Previously esbuild had a bug that caused esbuild to not handle these correctly in packages installed via Yarn's "Plug'n'Play" installation strategy. The problem was that subpath imports were being checked after Yarn PnP instead of before. This release reorders these checks, which should allow subpath imports to work in this case.
   915  
   916  * Link from JS to CSS in the metafile ([#1861](https://github.com/evanw/esbuild/issues/1861), [#2565](https://github.com/evanw/esbuild/issues/2565))
   917  
   918      When you import CSS into a bundled JS file, esbuild creates a parallel CSS bundle next to your JS bundle. So if `app.ts` imports some CSS files and you bundle it, esbuild will give you `app.js` and `app.css`. You would then add both `<script src="app.js"></script>` and `<link href="app.css" rel="stylesheet">` to your HTML to include everything in the page. This approach is more efficient than having esbuild insert additional JavaScript into `app.js` that downloads and includes `app.css` because it means the browser can download and parse both the CSS and the JS in parallel (and potentially apply the CSS before the JS has even finished downloading).
   919  
   920      However, sometimes it's difficult to generate the `<link>` tag. One case is when you've added `[hash]` to the [entry names](https://esbuild.github.io/api/#entry-names) setting to include a content hash in the file name. Then the file name will look something like `app-GX7G2SBE.css` and may change across subsequent builds. You can tell esbuild to generate build metadata using the `metafile` API option but the metadata only tells you which generated JS bundle corresponds to a JS entry point (via the `entryPoint` property), not which file corresponds to the associated CSS bundle. Working around this was hacky and involved string manipulation.
   921  
   922      This release adds the `cssBundle` property to the metafile to make this easier. It's present on the metadata for the generated JS bundle and points to the associated CSS bundle. So to generate the HTML tags for a given JS entry point, you first find the output file with the `entryPoint` you are looking for (and put that in a `<script>` tag), then check for the `cssBundle` property to find the associated CSS bundle (and put that in a `<link>` tag).
   923  
   924      One thing to note is that there is deliberately no `jsBundle` property mapping the other way because it's not a 1:1 relationship. Two JS bundles can share the same CSS bundle in the case where the associated CSS bundles have the same name and content. In that case there would be no one value for a hypothetical `jsBundle` property to have.
   925  
   926  ## 0.15.9
   927  
   928  * Fix an obscure npm package installation issue with `--omit=optional` ([#2558](https://github.com/evanw/esbuild/issues/2558))
   929  
   930      The previous release introduced a regression with `npm install esbuild --omit=optional` where the file `node_modules/.bin/esbuild` would no longer be present after installation. That could cause any package scripts which used the `esbuild` command to no longer work. This release fixes the regression so `node_modules/.bin/esbuild` should now be present again after installation. This regression only affected people installing esbuild using `npm` with either the `--omit=optional` or `--no-optional` flag, which is a somewhat unusual situation.
   931  
   932      **More details:**
   933  
   934      The reason for this regression is due to some obscure npm implementation details. Since the Go compiler doesn't support trivial cross-compiling on certain Android platforms, esbuild's installer installs a WebAssembly shim on those platforms instead. In the previous release I attempted to simplify esbuild's WebAssembly shims to depend on the `esbuild-wasm` package instead of including another whole copy of the WebAssembly binary (to make publishing faster and to save on file system space after installation). However, both the `esbuild` package and the `esbuild-wasm` package provide a binary called `esbuild` and it turns out that adding `esbuild-wasm` as a nested dependency of the `esbuild` package (specifically `esbuild` optionally depends on `@esbuild/android-arm` which depends on `esbuild-wasm`) caused npm to be confused about what `node_modules/.bin/esbuild` is supposed to be.
   935  
   936      It's pretty strange and unexpected that disabling the installation of optional dependencies altogether would suddenly cause an optional dependency's dependency to conflict with the top-level package. What happens under the hood is that if `--omit=optional` is present, npm attempts to uninstall the `esbuild-wasm` nested dependency at the end of `npm install` (even though the `esbuild-wasm` package was never installed due to `--omit=optional`). This uninstallation causes `node_modules/.bin/esbuild` to be deleted.
   937  
   938      After doing a full investigation, I discovered that npm's handling of the `.bin` directory is deliberately very brittle. When multiple packages in the dependency tree put something in `.bin` with the same name, the end result is non-deterministic/random. What you get in `.bin` might be from one package, from the other package, or might be missing entirely. The workaround suggested by npm is to just avoid having two packages that put something in `.bin` with the same name. So this was fixed by making the `@esbuild/android-arm` and `esbuild-android-64` packages each include another whole copy of the WebAssembly binary, which works because these packages don't put anything in `.bin`.
   939  
   940  ## 0.15.8
   941  
   942  * Fix JSX name collision edge case ([#2534](https://github.com/evanw/esbuild/issues/2534))
   943  
   944      Code generated by esbuild could have a name collision in the following edge case:
   945  
   946      * The JSX transformation mode is set to `automatic`, which causes `import` statements to be inserted
   947      * An element uses a `{...spread}` followed by a `key={...}`, which uses the legacy `createElement` fallback imported from `react`
   948      * Another import uses a name that ends with `react` such as `@remix-run/react`
   949      * The output format has been set to CommonJS so that `import` statements are converted into require calls
   950  
   951      In this case, esbuild previously generated two variables with the same name `import_react`, like this:
   952  
   953      ```js
   954      var import_react = require("react");
   955      var import_react2 = require("@remix-run/react");
   956      ```
   957  
   958      That bug is fixed in this release. The code generated by esbuild no longer contains a name collision.
   959  
   960  * Fall back to WebAssembly on Android ARM ([#1556](https://github.com/evanw/esbuild/issues/1556), [#1578](https://github.com/evanw/esbuild/issues/1578), [#2335](https://github.com/evanw/esbuild/issues/2335), [#2526](https://github.com/evanw/esbuild/issues/2526))
   961  
   962      Go's compiler supports trivial cross-compiling to almost all platforms without installing any additional software other than the Go compiler itself. This has made it very easy for esbuild to publish native binary executables for many platforms. However, it strangely doesn't support cross-compiling to Android ARM without installing the Android build tools.
   963  
   964      So instead of publishing a native esbuild binary executable to npm, this release publishes a WebAssembly fallback build. This is essentially the same as the `esbuild-wasm` package but it's installed automatically when you install the `esbuild` package on Android ARM. So packages that depend on the `esbuild` package should now work on Android ARM. This change has not yet been tested end-to-end because I don't have a 32-bit Android ARM device myself, but in theory it should work.
   965  
   966      This inherits the drawbacks of WebAssembly including significantly slower performance than native as well as potentially also more severe memory usage limitations and lack of certain features (e.g. `--serve`). If you want to use a native binary executable of esbuild on Android ARM, you may be able to build it yourself from source after installing the Android build tools.
   967  
   968  * Attempt to better support Yarn's `ignorePatternData` feature ([#2495](https://github.com/evanw/esbuild/issues/2495))
   969  
   970      Part of resolving paths in a project using Yarn's Plug'n'Play feature involves evaluating a regular expression in the `ignorePatternData` property of `.pnp.data.json`. However, it turns out that the particular regular expressions generated by Yarn use some syntax that works with JavaScript regular expressions but that does not work with Go regular expressions.
   971  
   972      In this release, esbuild will now strip some of the the problematic syntax from the regular expression before compiling it, which should hopefully allow it to be compiled by Go's regular expression engine. The specific character sequences that esbuild currently strips are as follows:
   973  
   974      * `(?!\.)`
   975      * `(?!(?:^|\/)\.)`
   976      * `(?!\.{1,2}(?:\/|$))`
   977      * `(?!(?:^|\/)\.{1,2}(?:\/|$))`
   978  
   979      These seem to be used by Yarn to avoid the `.` and `..` path segments in the middle of relative paths. The removal of these character sequences seems relatively harmless in this case since esbuild shouldn't ever generate such path segments. This change should add support to esbuild for Yarn's [`pnpIgnorePatterns`](https://yarnpkg.com/configuration/yarnrc/#pnpIgnorePatterns) feature.
   980  
   981  * Fix non-determinism issue with legacy block-level function declarations and strict mode ([#2537](https://github.com/evanw/esbuild/issues/2537))
   982  
   983      When function declaration statements are nested inside a block in strict mode, they are supposed to only be available within that block's scope. But in "sloppy mode" (which is what non-strict mode is commonly called), they are supposed to be available within the whole function's scope:
   984  
   985      ```js
   986      // This returns 1 due to strict mode
   987      function test1() {
   988        'use strict'
   989        function fn() { return 1 }
   990        if (true) { function fn() { return 2 } }
   991        return fn()
   992      }
   993  
   994      // This returns 2 due to sloppy mode
   995      function test2() {
   996        function fn() { return 1 }
   997        if (true) { function fn() { return 2 } }
   998        return fn()
   999      }
  1000      ```
  1001  
  1002      To implement this, esbuild compiles these two functions differently to reflect their different semantics:
  1003  
  1004      ```js
  1005      function test1() {
  1006        "use strict";
  1007        function fn() {
  1008          return 1;
  1009        }
  1010        if (true) {
  1011          let fn2 = function() {
  1012            return 2;
  1013          };
  1014        }
  1015        return fn();
  1016      }
  1017      function test2() {
  1018        function fn() {
  1019          return 1;
  1020        }
  1021        if (true) {
  1022          let fn2 = function() {
  1023            return 2;
  1024          };
  1025          var fn = fn2;
  1026        }
  1027        return fn();
  1028      }
  1029      ```
  1030  
  1031      However, the compilation had a subtle bug where the automatically-generated function-level symbols for multible hoisted block-level function declarations in the same block a sloppy-mode context were generated in a random order if the output was in strict mode, which could be the case if TypeScript's `alwaysStrict` setting was set to true. This lead to non-determinism in the output as the minifier would randomly exchange the generated names for these symbols on different runs. This bug has been fixed by sorting the keys of the unordered map before iterating over them.
  1032  
  1033  * Fix parsing of `@keyframes` with string identifiers ([#2555](https://github.com/evanw/esbuild/issues/2555))
  1034  
  1035      Firefox supports `@keyframes` with string identifier names. Previously this was treated as a syntax error by esbuild as it doesn't work in any other browser. The specification allows for this however, so it's technically not a syntax error (even though it would be unwise to use this feature at the moment). There was also a bug where esbuild would remove the identifier name in this case as the syntax wasn't recognized.
  1036  
  1037      This release changes esbuild's parsing of `@keyframes` to now consider this case to be an unrecognized CSS rule. That means it will be passed through unmodified (so you can now use esbuild to bundle this Firefox-specific CSS) but the CSS will not be pretty-printed or minified. I don't think it makes sense for esbuild to have special code to handle this Firefox-specific syntax at this time. This decision can be revisited in the future if other browsers add support for this feature.
  1038  
  1039  * Add the `--jsx-side-effects` API option ([#2539](https://github.com/evanw/esbuild/issues/2539), [#2546](https://github.com/evanw/esbuild/pull/2546))
  1040  
  1041      By default esbuild assumes that JSX expressions are side-effect free, which means they are annoated with `/* @__PURE__ */` comments and are removed during bundling when they are unused. This follows the common use of JSX for virtual DOM and applies to the vast majority of JSX libraries. However, some people have written JSX libraries that don't have this property. JSX expressions can have arbitrary side effects and can't be removed. If you are using such a library, you can now pass `--jsx-side-effects` to tell esbuild that JSX expressions have side effects so it won't remove them when they are unused.
  1042  
  1043      This feature was contributed by [@rtsao](https://github.com/rtsao).
  1044  
  1045  ## 0.15.7
  1046  
  1047  * Add `--watch=forever` to allow esbuild to never terminate ([#1511](https://github.com/evanw/esbuild/issues/1511), [#1885](https://github.com/evanw/esbuild/issues/1885))
  1048  
  1049      Currently using esbuild's watch mode via `--watch` from the CLI will stop watching if stdin is closed. The rationale is that stdin is automatically closed by the OS when the parent process exits, so stopping watch mode when stdin is closed ensures that esbuild's watch mode doesn't keep running forever after the parent process has been closed. For example, it would be bad if you wrote a shell script that did `esbuild --watch &` to run esbuild's watch mode in the background, and every time you run the script it creates a new `esbuild` process that runs forever.
  1050  
  1051      However, there are cases when it makes sense for esbuild's watch mode to never exit. One such case is within a short-lived VM where the lifetime of all processes inside the VM is expected to be the lifetime of the VM. Previously you could easily do this by piping the output of a long-lived command into esbuild's stdin such as `sleep 999999999 | esbuild --watch &`. However, this possibility often doesn't occur to people, and it also doesn't work on Windows. People also sometimes attempt to keep esbuild open by piping an infinite stream of data to esbuild such as with `esbuild --watch </dev/zero &` which causes esbuild to spin at 100% CPU. So with this release, esbuild now has a `--watch=forever` flag that will not stop watch mode when stdin is closed.
  1052  
  1053  * Work around `PATH` without `node` in install script ([#2519](https://github.com/evanw/esbuild/issues/2519))
  1054  
  1055      Some people install esbuild's npm package in an environment without the `node` command in their `PATH`. This fails on Windows because esbuild's install script runs the `esbuild` command before exiting as a sanity check, and on Windows the `esbuild` command has to be a JavaScript file because of some internal details about how npm handles the `bin` folder (specifically the `esbuild` command lacks the `.exe` extension, which is required on Windows). This release attempts to work around this problem by using `process.execPath` instead of `"node"` as the command for running node. In theory this means the installer can now still function on Windows if something is wrong with `PATH`.
  1056  
  1057  ## 0.15.6
  1058  
  1059  * Lower `for await` loops ([#1930](https://github.com/evanw/esbuild/issues/1930))
  1060  
  1061      This release lowers `for await` loops to the equivalent `for` loop containing `await` when esbuild is configured such that `for await` loops are unsupported. This transform still requires at least generator functions to be supported since esbuild's lowering of `await` currently relies on generators. This new transformation is mostly modeled after what the TypeScript compiler does. Here's an example:
  1062  
  1063      ```js
  1064      async function f() {
  1065        for await (let x of y)
  1066          x()
  1067      }
  1068      ```
  1069  
  1070      The code above will now become the following code with `--target=es2017` (omitting the code for the `__forAwait` helper function):
  1071  
  1072      ```js
  1073      async function f() {
  1074        try {
  1075          for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
  1076            let x = temp.value;
  1077            x();
  1078          }
  1079        } catch (temp) {
  1080          error = [temp];
  1081        } finally {
  1082          try {
  1083            more && (temp = iter.return) && await temp.call(iter);
  1084          } finally {
  1085            if (error)
  1086              throw error[0];
  1087          }
  1088        }
  1089      }
  1090      ```
  1091  
  1092  * Automatically fix invalid `supported` configurations ([#2497](https://github.com/evanw/esbuild/issues/2497))
  1093  
  1094      The `--target=` setting lets you tell esbuild to target a specific version of one or more JavaScript runtimes such as `chrome80,node14` and esbuild will restrict its output to only those features supported by all targeted JavaScript runtimes. More recently, esbuild introduced the `--supported:` setting that lets you override which features are supported on a per-feature basis. However, this now lets you configure nonsensical things such as `--supported:async-await=false --supported:async-generator=true`. Previously doing this could result in esbuild building successfully but producing invalid output.
  1095  
  1096      Starting with this release, esbuild will now attempt to automatically fix nonsensical feature override configurations by introducing more overrides until the configuration makes sense. So now the configuration from previous example will be changed such that `async-await=false` implies `async-generator=false`. The full list of implications that were introduced is below:
  1097  
  1098      * `async-await=false` implies:
  1099          * `async-generator=false`
  1100          * `for-await=false`
  1101          * `top-level-await=false`
  1102  
  1103      * `generator=false` implies:
  1104          * `async-generator=false`
  1105  
  1106      * `object-accessors=false` implies:
  1107          * `class-private-accessor=false`
  1108          * `class-private-static-accessor=false`
  1109  
  1110      * `class-field=false` implies:
  1111          * `class-private-field=false`
  1112  
  1113      * `class-static-field=false` implies:
  1114          * `class-private-static-field=false`
  1115  
  1116      * `class=false` implies:
  1117          * `class-field=false`
  1118          * `class-private-accessor=false`
  1119          * `class-private-brand-check=false`
  1120          * `class-private-field=false`
  1121          * `class-private-method=false`
  1122          * `class-private-static-accessor=false`
  1123          * `class-private-static-field=false`
  1124          * `class-private-static-method=false`
  1125          * `class-static-blocks=false`
  1126          * `class-static-field=false`
  1127  
  1128  * Implement a small minification improvement ([#2496](https://github.com/evanw/esbuild/issues/2496))
  1129  
  1130      Some people write code that contains a label with an immediate break such as `x: break x`. Previously this code was not removed during minification but it will now be removed during minification starting with this release.
  1131  
  1132  * Fix installing esbuild via Yarn with `enableScripts: false` configured ([#2457](https://github.com/evanw/esbuild/pull/2457))
  1133  
  1134      If esbuild is installed with Yarn with the `enableScripts: false` setting configured, then Yarn will not "unplug" the `esbuild` package (i.e. it will keep the entire package inside a `.zip` file). This messes with esbuild's library code that extracts the platform-specific binary executable because that code copies the binary executable into the esbuild package directory, and Yarn's `.zip` file system shim doesn't let you write to a directory inside of a `.zip` file. This release fixes this problem by writing to the `node_modules/.cache/esbuild` directory instead in this case. So you should now be able to use esbuild with Yarn when `enableScripts: false` is configured.
  1135  
  1136      This fix was contributed by [@jonaskuske](https://github.com/jonaskuske).
  1137  
  1138  ## 0.15.5
  1139  
  1140  * Fix issues with Yarn PnP and Yarn's workspaces feature ([#2476](https://github.com/evanw/esbuild/issues/2476))
  1141  
  1142      This release makes sure esbuild works with a Yarn feature called [workspaces](https://yarnpkg.com/features/workspaces/). Previously esbuild wasn't tested in this scenario, but this scenario now has test coverage. Getting this to work involved further tweaks to esbuild's custom code for what happens after Yarn PnP's path resolution algorithm runs, which is not currently covered by Yarn's PnP specification. These tweaks also fix `exports` map resolution with Yarn PnP for non-empty subpaths, which wasn't previously working.
  1143  
  1144  ## 0.15.4
  1145  
  1146  * Consider TypeScript import assignments to be side-effect free ([#2468](https://github.com/evanw/esbuild/issues/2468))
  1147  
  1148      TypeScript has a [legacy import syntax](https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases) for working with TypeScript namespaces that looks like this:
  1149  
  1150      ```ts
  1151      import { someNamespace } from './some-file'
  1152      import bar = someNamespace.foo;
  1153  
  1154      // some-file.ts
  1155      export namespace someNamespace {
  1156        export let foo = 123
  1157      }
  1158      ```
  1159  
  1160      Since esbuild converts TypeScript into JavaScript one file at a time, it doesn't know if `bar` is supposed to be a value or a type (or both, which TypeScript actually allows in this case). This is problematic because values are supposed to be kept during the conversion but types are supposed to be removed during the conversion. Currently esbuild keeps `bar` in the output, which is done because `someNamespace.foo` is a property access and property accesses run code that could potentially have a side effect (although there is no side effect in this case).
  1161  
  1162      With this release, esbuild will now consider `someNamespace.foo` to have no side effects. This means `bar` will now be removed when bundling and when tree shaking is enabled. Note that it will still not be removed when tree shaking is disabled. This is because in this mode, esbuild supports adding additional code to the end of the generated output that's in the same scope as the module. That code could potentially make use of `bar`, so it would be incorrect to remove it. If you want `bar` to be removed, you'll have to enable tree shaking (which tells esbuild that nothing else depends on the unexported top-level symbols in the generated output).
  1163  
  1164  * Change the order of the banner and the `"use strict"` directive ([#2467](https://github.com/evanw/esbuild/issues/2467))
  1165  
  1166      Previously the top of the file contained the following things in order:
  1167  
  1168      1. The hashbang comment (see below) from the source code, if present
  1169      2. The `"use strict"` directive from the source code, if present
  1170      3. The content of esbuild's `banner` API option, if specified
  1171  
  1172      This was problematic for people that used the `banner` API option to insert the hashbang comment instead of using esbuild's hashbang comment preservation feature. So with this release, the order has now been changed to:
  1173  
  1174      1. The hashbang comment (see below) from the source code, if present
  1175      2. The content of esbuild's `banner` API option, if specified
  1176      3. The `"use strict"` directive from the source code, if present
  1177  
  1178      I'm considering this change to be a bug fix instead of a breaking change because esbuild's documentation states that the `banner` API option can be used to "insert an arbitrary string at the beginning of generated JavaScript files". While this isn't technically true because esbuild may still insert the original hashbang comment before the banner, it's at least more correct now because the banner will now come before the `"use strict"` directive.
  1179  
  1180      For context: JavaScript files recently allowed using a [hashbang comment](https://github.com/tc39/proposal-hashbang), which starts with `#!` and which must start at the very first character of the file. It allows Unix systems to execute the file directly as a script without needing to prefix it by the `node` command. This comment typically has the value `#!/usr/bin/env node`. Hashbang comments will be a part of ES2023 when it's released next year.
  1181  
  1182  * Fix `exports` maps with Yarn PnP path resolution ([#2473](https://github.com/evanw/esbuild/issues/2473))
  1183  
  1184      The Yarn PnP specification says that to resolve a package path, you first resolve it to the absolute path of a directory, and then you run node's module resolution algorithm on it. Previously esbuild followed this part of the specification. However, doing this means that `exports` in `package.json` is not respected because node's module resolution algorithm doesn't interpret `exports` for absolute paths. So with this release, esbuild will now use a modified algorithm that deviates from both specifications but that should hopefully behave more similar to what Yarn actually does: node's module resolution algorithm is run with the original import path but starting from the directory returned by Yarn PnP.
  1185  
  1186  ## 0.15.3
  1187  
  1188  * Change the Yarn PnP manifest to a singleton ([#2463](https://github.com/evanw/esbuild/issues/2463))
  1189  
  1190      Previously esbuild searched for the Yarn PnP manifest in the parent directories of each file. But with Yarn's `enableGlobalCache` setting it's possible to configure Yarn PnP's implementation to reach outside of the directory subtree containing the Yarn PnP manifest. This was causing esbuild to fail to bundle projects with the `enableGlobalCache` setting enabled.
  1191  
  1192      To handle this case, *esbuild will now only search for the Yarn PnP manifest in the current working directory of the esbuild process*. If you're using esbuild's CLI, this means you will now have to `cd` into the appropriate directory first. If you're using esbuild's API, you can override esbuild's value for the current working directory with the `absWorkingDir` API option.
  1193  
  1194  * Fix Yarn PnP resolution failures due to backslashes in paths on Windows ([#2462](https://github.com/evanw/esbuild/issues/2462))
  1195  
  1196      Previously dependencies of a Yarn PnP virtual dependency failed to resolve on Windows. This was because Windows uses `\` instead of `/` as a path separator, and the path manipulation algorithms used for Yarn PnP expected `/`. This release converts `\` into `/` in Windows paths, which fixes this issue.
  1197  
  1198  * Fix `sideEffects` patterns containing slashes on Windows ([#2465](https://github.com/evanw/esbuild/issues/2465))
  1199  
  1200      The `sideEffects` field in `package.json` lets you specify an array of patterns to mark which files have side effects (which causes all other files to be considered to not have side effects by exclusion). That looks like this:
  1201  
  1202      ```json
  1203      "sideEffects": [
  1204        "**/index.js",
  1205        "**/index.prod.js"
  1206      ]
  1207      ```
  1208  
  1209      However, the presence of the `/` character in the pattern meant that the pattern failed to match Windows-style paths, which broke `sideEffects` on Windows in this case. This release fixes this problem by adding additional code to handle Windows-style paths.
  1210  
  1211  ## 0.15.2
  1212  
  1213  * Fix Yarn PnP issue with packages containing `index.js` ([#2455](https://github.com/evanw/esbuild/issues/2455), [#2461](https://github.com/evanw/esbuild/issues/2461))
  1214  
  1215      Yarn PnP's tests require the resolved paths to end in `/`. That's not how the rest of esbuild's internals work, however, and doing this messed up esbuild's node module path resolution regarding automatically-detected `index.js` files. Previously packages that relied on implicit `index.js` resolution rules didn't work with esbuild under Yarn PnP. Removing this slash has fixed esbuild's path resolution behavior regarding `index.js`, which should now the same both with and without Yarn PnP.
  1216  
  1217  * Fix Yarn PnP support for `extends` in `tsconfig.json` ([#2456](https://github.com/evanw/esbuild/issues/2456))
  1218  
  1219      Previously using `extends` in `tsconfig.json` with a path in a Yarn PnP package didn't work. This is because the process of setting up package path resolution rules requires parsing `tsconfig.json` files (due to the `baseUrl` and `paths` features) and resolving `extends` to a package path requires package path resolution rules to already be set up, which is a circular dependency. This cycle is broken by using special rules for `extends` in `tsconfig.json` that bypasses esbuild's normal package path resolution process. This is why using `extends` with a Yarn PnP package didn't automatically work. With this release, these special rules have been modified to check for a Yarn PnP manifest so this case should work now.
  1220  
  1221  * Fix Yarn PnP support in `esbuild-wasm` ([#2458](https://github.com/evanw/esbuild/issues/2458))
  1222  
  1223      When running esbuild via WebAssembly, Yarn PnP support previously failed because Go's file system internals return `EINVAL` when trying to read a `.zip` file as a directory when run with WebAssembly. This was unexpected because Go's file system internals return `ENOTDIR` for this case on native. This release updates esbuild to treat `EINVAL` like `ENOTDIR` in this case, which fixes using `esbuild-wasm` to bundle a Yarn PnP project.
  1224  
  1225      Note that to be able to use `esbuild-wasm` for Yarn PnP successfully, you currently have to run it using `node` instead of `yarn node`. This is because the file system shim that Yarn overwrites node's native file system API with currently generates invalid file descriptors with negative values when inside a `.zip` file. This prevents esbuild from working correctly because Go's file system internals don't expect syscalls that succeed without an error to return an invalid file descriptor. Yarn is working on fixing their use of invalid file descriptors.
  1226  
  1227  ## 0.15.1
  1228  
  1229  * Update esbuild's Yarn Plug'n'Play implementation to match the latest specification changes ([#2452](https://github.com/evanw/esbuild/issues/2452), [#2453](https://github.com/evanw/esbuild/pull/2453))
  1230  
  1231      This release updates esbuild's implementation of Yarn Plug'n'Play to match some changes to Yarn's specification that just landed. The changes are as follows:
  1232  
  1233      * Check for platform-specific absolute paths instead of always for the `/` prefix
  1234  
  1235          The specification previously said that Yarn Plug'n'Play path resolution rules should not apply for paths that start with `/`. The intent was to avoid accidentally processing absolute paths. However, absolute paths on Windows such as `C:\project` start with drive letters instead of with `/`. So the specification was changed to instead explicitly avoid processing absolute paths.
  1236  
  1237      * Make `$$virtual` an alias for `__virtual__`
  1238  
  1239          Supporting Yarn-style path resolution requires implementing a custom Yarn-specific path traversal scheme where certain path segments are considered no-ops. Specifically any path containing segments of the form `__virtual__/<whatever>/<n>` where `<n>` is an integer must be treated as if they were `n` times the `..` operator instead (the `<whatever>` path segment is ignored). So `/path/to/project/__virtual__/xyz/2/foo.js` maps to the underlying file `/path/to/project/../../foo.js`. This scheme makes it possible for Yarn to get node (and esbuild) to load the same file multiple times (which is sometimes required for correctness) without actually duplicating the file on the file system.
  1240  
  1241          However, old versions of Yarn used to use `$$virtual` instead of `__virtual__`. This was changed because `$$virtual` was error-prone due to the use of the `$` character, which can cause bugs when it's not correctly escaped within regular expressions. Now that esbuild makes `$$virtual` an alias for `__virtual__`, esbuild should now work with manifests from these old Yarn versions.
  1242  
  1243      * Ignore PnP manifests in virtual directories
  1244  
  1245          The specification describes the algorithm for how to find the Plug'n'Play manifest when starting from a certain point in the file system: search through all parent directories in reverse order until the manifest is found. However, this interacts poorly with virtual paths since it can end up finding a virtual copy of the manifest instead of the original. To avoid this, esbuild now ignores manifests in virtual directories so that the search for the manifest will continue and find the original manifest in another parent directory later on.
  1246  
  1247      These fixes mean that esbuild's implementation of Plug'n'Play now matches Yarn's implementation more closely, and esbuild can now correctly build more projects that use Plug'n'Play.
  1248  
  1249  ## 0.15.0
  1250  
  1251  **This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.14.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.
  1252  
  1253  * Implement the Yarn Plug'n'Play module resolution algorithm ([#154](https://github.com/evanw/esbuild/issues/154), [#237](https://github.com/evanw/esbuild/issues/237), [#1263](https://github.com/evanw/esbuild/issues/1263), [#2451](https://github.com/evanw/esbuild/pull/2451))
  1254  
  1255      [Node](https://nodejs.org/) comes with a package manager called [npm](https://www.npmjs.com/), which installs packages into a `node_modules` folder. Node and esbuild both come with built-in rules for resolving import paths to packages within `node_modules`, so packages installed via npm work automatically without any configuration. However, many people use an alternative package manager called [Yarn](https://yarnpkg.com/). While Yarn can install packages using `node_modules`, it also offers a different package installation strategy called [Plug'n'Play](https://yarnpkg.com/features/pnp/), which is often shortened to "PnP" (not to be confused with [pnpm](https://pnpm.io/), which is an entirely different unrelated package manager).
  1256  
  1257      Plug'n'Play installs packages as `.zip` files on your file system. The packages are never actually unzipped. Since Node doesn't know anything about Yarn's package installation strategy, this means you can no longer run your code with Node as it won't be able to find your packages. Instead, you need to run your code with Yarn, which applies patches to Node's file system APIs before running your code. These patches attempt to make zip files seem like normal directories. When running under Yarn, using Node's file system API to read `./some.zip/lib/file.js` actually automatically extracts `lib/file.js` from `./some.zip` at run-time as if it was a normal file. Other file system APIs behave similarly. However, these patches don't work with esbuild because esbuild is not written in JavaScript; it's a native binary executable that interacts with the file system directly through the operating system.
  1258  
  1259      Previously the workaround for using esbuild with Plug'n'Play was to use the [`@yarnpkg/esbuild-plugin-pnp`](https://www.npmjs.com/package/@yarnpkg/esbuild-plugin-pnp) plugin with esbuild's JavaScript API. However, this wasn't great because the plugin needed to potentially intercept every single import path and file load to check whether it was a Plug'n'Play package, which has an unusually high performance cost. It also meant that certain subtleties of path resolution rules within a `.zip` file could differ slightly from the way esbuild normally works since path resolution inside `.zip` files was implemented by Yarn, not by esbuild (which is due to a limitation of esbuild's plugin API).
  1260  
  1261      With this release, esbuild now contains an independent implementation of Yarn's Plug'n'Play algorithm (which is used when esbuild finds a `.pnp.js`, `.pnp.cjs`, or `.pnp.data.json` file in the directory tree). Creating additional implementations of this algorithm recently became possible because Yarn's package manifest format was recently documented: https://yarnpkg.com/advanced/pnp-spec/. This should mean that you can now use esbuild to bundle Plug'n'Play projects without any additional configuration (so you shouldn't need `@yarnpkg/esbuild-plugin-pnp` anymore). Bundling these projects should now happen much faster as Yarn no longer even needs to be run at all. Bundling the Yarn codebase itself with esbuild before and after this change seems to demonstrate over a 10x speedup (3.4s to 0.24s). And path resolution rules within Yarn packages should now be consistent with how esbuild handles regular Node packages. For example, fields such as `module` and `browser` in `package.json` files within `.zip` files should now be respected.
  1262  
  1263      Keep in mind that this is brand new code and there may be some initial issues to work through before esbuild's implementation is solid. Yarn's Plug'n'Play specification is also brand new and may need some follow-up edits to guide new implementations to match Yarn's exact behavior. If you try this out, make sure to test it before committing to using it, and let me know if anything isn't working as expected. Should you need to debug esbuild's path resolution, you may find `--log-level=verbose` helpful.
  1264  
  1265  ## 0.14.54
  1266  
  1267  * Fix optimizations for calls containing spread arguments ([#2445](https://github.com/evanw/esbuild/issues/2445))
  1268  
  1269      This release fixes the handling of spread arguments in the optimization of `/* @__PURE__ */` comments, empty functions, and identity functions:
  1270  
  1271      ```js
  1272      // Original code
  1273      function empty() {}
  1274      function identity(x) { return x }
  1275      /* @__PURE__ */ a(...x)
  1276      /* @__PURE__ */ new b(...x)
  1277      empty(...x)
  1278      identity(...x)
  1279  
  1280      // Old output (with --minify --tree-shaking=true)
  1281      ...x;...x;...x;...x;
  1282  
  1283      // New output (with --minify --tree-shaking=true)
  1284      function identity(n){return n}[...x];[...x];[...x];identity(...x);
  1285      ```
  1286  
  1287      Previously esbuild assumed arguments with side effects could be directly inlined. This is almost always true except for spread arguments, which are not syntactically valid on their own and which have the side effect of causing iteration, which might have further side effects. Now esbuild will wrap these elements in an unused array so that they are syntactically valid and so that the iteration side effects are preserved.
  1288  
  1289  ## 0.14.53
  1290  
  1291  This release fixes a minor issue with the previous release: I had to rename the package `esbuild-linux-loong64` to `@esbuild/linux-loong64` in the contributed PR because someone registered the package name before I could claim it, and I missed a spot. Hopefully everything is working after this release. I plan to change all platform-specific package names to use the `@esbuild/` scope at some point to avoid this problem in the future.
  1292  
  1293  ## 0.14.52
  1294  
  1295  * Allow binary data as input to the JS `transform` and `build` APIs ([#2424](https://github.com/evanw/esbuild/issues/2424))
  1296  
  1297      Previously esbuild's `transform` and `build` APIs could only take a string. However, some people want to use esbuild to convert binary data to base64 text. This is problematic because JavaScript strings represent UTF-16 text and esbuild internally operates on arrays of bytes, so all strings coming from JavaScript undergo UTF-16 to UTF-8 conversion before use. This meant that using esbuild in this way was doing base64 encoding of the UTF-8 encoding of the text, which was undesired.
  1298  
  1299      With this release, esbuild now accepts `Uint8Array` in addition to string as an input format for the `transform` and `build` APIs. Now you can use esbuild to convert binary data to base64 text:
  1300  
  1301      ```js
  1302      // Original code
  1303      import esbuild from 'esbuild'
  1304      console.log([
  1305        (await esbuild.transform('\xFF', { loader: 'base64' })).code,
  1306        (await esbuild.build({ stdin: { contents: '\xFF', loader: 'base64' }, write: false })).outputFiles[0].text,
  1307      ])
  1308      console.log([
  1309        (await esbuild.transform(new Uint8Array([0xFF]), { loader: 'base64' })).code,
  1310        (await esbuild.build({ stdin: { contents: new Uint8Array([0xFF]), loader: 'base64' }, write: false })).outputFiles[0].text,
  1311      ])
  1312  
  1313      // Old output
  1314      [ 'module.exports = "w78=";\n', 'module.exports = "w78=";\n' ]
  1315      /* ERROR: The input to "transform" must be a string */
  1316  
  1317      // New output
  1318      [ 'module.exports = "w78=";\n', 'module.exports = "w78=";\n' ]
  1319      [ 'module.exports = "/w==";\n', 'module.exports = "/w==";\n' ]
  1320      ```
  1321  
  1322  * Update the getter for `text` in build results ([#2423](https://github.com/evanw/esbuild/issues/2423))
  1323  
  1324      Output files in build results returned from esbuild's JavaScript API have both a `contents` and a `text` property to return the contents of the output file. The `contents` property is a binary UTF-8 Uint8Array and the `text` property is a JavaScript UTF-16 string. The `text` property is a getter that does the UTF-8 to UTF-16 conversion only if it's needed for better performance.
  1325  
  1326      Previously if you mutate the build results object, you had to overwrite both `contents` and `text` since the value returned from the `text` getter is the original text returned by esbuild. Some people find this confusing so with this release, the getter for `text` has been updated to do the UTF-8 to UTF-16 conversion on the current value of the `contents` property instead of the original value.
  1327  
  1328  * Publish builds for Linux LoongArch 64-bit ([#1804](https://github.com/evanw/esbuild/issues/1804), [#2373](https://github.com/evanw/esbuild/pull/2373))
  1329  
  1330      This release upgrades to [Go 1.19](https://go.dev/doc/go1.19), which now includes support for LoongArch 64-bit processors. LoongArch 64-bit builds of esbuild will now be published to npm, which means that in theory they can now be installed with `npm install esbuild`. This was contributed by [@beyond-1234](https://github.com/beyond-1234).
  1331  
  1332  ## 0.14.51
  1333  
  1334  * Add support for React 17's `automatic` JSX transform ([#334](https://github.com/evanw/esbuild/issues/334), [#718](https://github.com/evanw/esbuild/issues/718), [#1172](https://github.com/evanw/esbuild/issues/1172), [#2318](https://github.com/evanw/esbuild/issues/2318), [#2349](https://github.com/evanw/esbuild/pull/2349))
  1335  
  1336      This adds support for the [new "automatic" JSX runtime from React 17+](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) to esbuild for both the build and transform APIs.
  1337  
  1338      **New CLI flags and API options:**
  1339      - `--jsx`, `jsx` &mdash; Set this to `"automatic"` to opt in to this new transform
  1340      - `--jsx-dev`, `jsxDev` &mdash; Toggles development mode for the automatic runtime
  1341      - `--jsx-import-source`, `jsxImportSource` &mdash; Overrides the root import for runtime functions (default `"react"`)
  1342  
  1343      **New JSX pragma comments:**
  1344      - `@jsxRuntime` &mdash; Sets the runtime (`automatic` or `classic`)
  1345      - `@jsxImportSource` &mdash; Sets the import source (only valid with automatic runtime)
  1346  
  1347      The existing `@jsxFragment` and `@jsxFactory` pragma comments are only valid with "classic" runtime.
  1348  
  1349      **TSConfig resolving:**
  1350      Along with accepting the new options directly via CLI or API, option inference from `tsconfig.json` compiler options was also implemented:
  1351  
  1352      - `"jsx": "preserve"` or `"jsx": "react-native"` &rarr; Same as `--jsx=preserve` in esbuild
  1353      - `"jsx": "react"` &rarr; Same as `--jsx=transform` in esbuild (which is the default behavior)
  1354      - `"jsx": "react-jsx"` &rarr; Same as `--jsx=automatic` in esbuild
  1355      - `"jsx": "react-jsxdev"` &rarr; Same as `--jsx=automatic --jsx-dev` in esbuild
  1356  
  1357      It also reads the value of `"jsxImportSource"` from `tsconfig.json` if specified.
  1358  
  1359      For `react-jsx` it's important to note that it doesn't implicitly disable `--jsx-dev`. This is to support the case where a user sets `"react-jsx"` in their `tsconfig.json` but then toggles development mode directly in esbuild.
  1360  
  1361      **esbuild vs Babel vs TS vs...**
  1362  
  1363      There are a few differences between the various technologies that implement automatic JSX runtimes. The JSX transform in esbuild follows a mix of Babel's and TypeScript's behavior:
  1364  
  1365      - When an element has `__source` or `__self` props:
  1366          - Babel: Print an error about a deprecated transform plugin
  1367          - TypeScript: Allow the props
  1368          - swc: Hard crash
  1369          - **esbuild**: Print an error &mdash; Following Babel was chosen for this one because this might help people catch configuration issues where JSX files are being parsed by multiple tools
  1370  
  1371      - Element has an "implicit true" key prop, e.g. `<a key />`:
  1372          - Babel: Print an error indicating that "key" props require an explicit value
  1373          - TypeScript: Silently omit the "key" prop
  1374          - swc: Hard crash
  1375          - **esbuild**: Print an error like Babel &mdash; This might help catch legitimate programming mistakes
  1376  
  1377      - Element has spread children, e.g. `<a>{...children}</a>`
  1378          - Babel: Print an error stating that React doesn't support spread children
  1379          - TypeScript: Use static jsx function and pass children as-is, including spread operator
  1380          - swc: same as Babel
  1381          - **esbuild**: Same as TypeScript
  1382  
  1383      Also note that TypeScript has some bugs regarding JSX development mode and the generation of `lineNumber` and `columnNumber` values. Babel's values are accurate though, so esbuild's line and column numbers match Babel. Both numbers are 1-based and columns are counted in terms of UTF-16 code units.
  1384  
  1385      This feature was contributed by [@jgoz](https://github.com/jgoz).
  1386  
  1387  ## 0.14.50
  1388  
  1389  * Emit `names` in source maps ([#1296](https://github.com/evanw/esbuild/issues/1296))
  1390  
  1391      The [source map specification](https://sourcemaps.info/spec.html) includes an optional `names` field that can associate an identifier with a mapping entry. This can be used to record the original name for an identifier, which is useful if the identifier was renamed to something else in the generated code. When esbuild was originally written, this field wasn't widely used, but now there are some debuggers that make use of it to provide better debugging of minified code. With this release, esbuild now includes a `names` field in the source maps that it generates. To save space, the original name is only recorded when it's different from the final name.
  1392  
  1393  * Update parser for arrow functions with initial default type parameters in `.tsx` files ([#2410](https://github.com/evanw/esbuild/issues/2410))
  1394  
  1395      TypeScript 4.6 introduced a [change to the parsing of JSX syntax in `.tsx` files](https://github.com/microsoft/TypeScript/issues/47062). Now a `<` token followed by an identifier and then a `=` token is parsed as an arrow function with a default type parameter instead of as a JSX element. This release updates esbuild's parser to match TypeScript's parser.
  1396  
  1397  * Fix an accidental infinite loop with `--define` substitution ([#2407](https://github.com/evanw/esbuild/issues/2407))
  1398  
  1399      This is a fix for a regression that was introduced in esbuild version 0.14.44 where certain `--define` substitutions could result in esbuild crashing with a stack overflow. The problem was an incorrect fix for #2292. The fix merged the code paths for `--define` and `--jsx-factory` rewriting since the value substitution is now the same for both. However, doing this accidentally made `--define` substitution recursive since the JSX factory needs to be able to match against `--define` substitutions to integrate with the `--inject` feature. The fix is to only do one additional level of matching against define substitutions, and to only do this for JSX factories. Now these cases are able to build successfully without a stack overflow.
  1400  
  1401  * Include the "public path" value in hashes ([#2403](https://github.com/evanw/esbuild/issues/2403))
  1402  
  1403      The `--public-path=` configuration value affects the paths that esbuild uses to reference files from other files and is used in various situations such as cross-chunk imports in JS and references to asset files from CSS files. However, it wasn't included in the hash calculations used for file names due to an oversight. This meant that changing the public path setting incorrectly didn't result in the hashes in file names changing even though the contents of the files changed. This release fixes the issue by including a hash of the public path in all non-asset output files.
  1404  
  1405  * Fix a cross-platform consistency bug ([#2383](https://github.com/evanw/esbuild/issues/2383))
  1406  
  1407      Previously esbuild would minify `0xFFFF_FFFF_FFFF_FFFF` as `0xffffffffffffffff` (18 bytes) on arm64 chips and as `18446744073709552e3` (19 bytes) on x86_64 chips. The reason was that the number was converted to a 64-bit unsigned integer internally for printing as hexadecimal, the 64-bit floating-point number `0xFFFF_FFFF_FFFF_FFFF` is actually `0x1_0000_0000_0000_0180` (i.e. it's rounded up, not down), and converting `float64` to `uint64` is implementation-dependent in Go when the input is out of bounds. This was fixed by changing the upper limit for which esbuild uses hexadecimal numbers during minification to `0xFFFF_FFFF_FFFF_F800`, which is the next representable 64-bit floating-point number below `0x1_0000_0000_0000_0180`, and which fits in a `uint64`. As a result, esbuild will now consistently never minify `0xFFFF_FFFF_FFFF_FFFF` as `0xffffffffffffffff` anymore, which means the output should now be consistent across platforms.
  1408  
  1409  * Fix a hang with the synchronous API when the package is corrupted ([#2396](https://github.com/evanw/esbuild/issues/2396))
  1410  
  1411      An error message is already thrown when the esbuild package is corrupted and esbuild can't be run. However, if you are using a synchronous call in the JavaScript API in worker mode, esbuild will use a child worker to initialize esbuild once so that the overhead of initializing esbuild can be amortized across multiple synchronous API calls. However, errors thrown during initialization weren't being propagated correctly which resulted in a hang while the main thread waited forever for the child worker to finish initializing. With this release, initialization errors are now propagated correctly so calling a synchronous API call when the package is corrupted should now result in an error instead of a hang.
  1412  
  1413  * Fix `tsconfig.json` files that collide with directory names ([#2411](https://github.com/evanw/esbuild/issues/2411))
  1414  
  1415      TypeScript lets you write `tsconfig.json` files with `extends` clauses that refer to another config file using an implicit `.json` file extension. However, if the config file without the `.json` extension existed as a directory name, esbuild and TypeScript had different behavior. TypeScript ignores the directory and continues looking for the config file by adding the `.json` extension while esbuild previously terminated the search and then failed to load the config file (because it's a directory). With this release, esbuild will now ignore exact matches when resolving `extends` fields in `tsconfig.json` files if the exact match results in a directory.
  1416  
  1417  * Add `platform` to the transform API ([#2362](https://github.com/evanw/esbuild/issues/2362))
  1418  
  1419      The `platform` option is mainly relevant for bundling because it mostly affects path resolution (e.g. activating the `"browser"` field in `package.json` files), so it was previously only available for the build API. With this release, it has additionally be made available for the transform API for a single reason: you can now set `--platform=node` when transforming a string so that esbuild will add export annotations for node, which is only relevant when `--format=cjs` is also present.
  1420  
  1421      This has to do with an implementation detail of node that parses the AST of CommonJS files to discover named exports when importing CommonJS from ESM. However, this new addition to esbuild's API is of questionable usefulness. Node's loader API (the main use case for using esbuild's transform API like this) actually bypasses the content returned from the loader and parses the AST that's present on the file system, so you won't actually be able to use esbuild's API for this. See the linked issue for more information.
  1422  
  1423  ## 0.14.49
  1424  
  1425  * Keep inlined constants when direct `eval` is present ([#2361](https://github.com/evanw/esbuild/issues/2361))
  1426  
  1427      Version 0.14.19 of esbuild added inlining of certain `const` variables during minification, which replaces all references to the variable with the initializer and then removes the variable declaration. However, this could generate incorrect code when direct `eval` is present because the direct `eval` could reference the constant by name. This release fixes the problem by preserving the `const` variable declaration in this case:
  1428  
  1429      ```js
  1430      // Original code
  1431      console.log((() => { const x = 123; return x + eval('x') }))
  1432  
  1433      // Old output (with --minify)
  1434      console.log(()=>123+eval("x"));
  1435  
  1436      // New output (with --minify)
  1437      console.log(()=>{const x=123;return 123+eval("x")});
  1438      ```
  1439  
  1440  * Fix an incorrect error in TypeScript when targeting ES5 ([#2375](https://github.com/evanw/esbuild/issues/2375))
  1441  
  1442      Previously when compiling TypeScript code to ES5, esbuild could incorrectly consider the following syntax forms as a transformation error:
  1443  
  1444      ```ts
  1445      0 ? ([]) : 1 ? ({}) : 2;
  1446      ```
  1447  
  1448      The error messages looked like this:
  1449  
  1450      ```
  1451      ✘ [ERROR] Transforming destructuring to the configured target environment ("es5") is not supported yet
  1452  
  1453          example.ts:1:5:
  1454            1 │ 0 ? ([]) : 1 ? ({}) : 2;
  1455              ╵      ^
  1456  
  1457      ✘ [ERROR] Transforming destructuring to the configured target environment ("es5") is not supported yet
  1458  
  1459          example.ts:1:16:
  1460            1 │ 0 ? ([]) : 1 ? ({}) : 2;
  1461              ╵                 ^
  1462      ```
  1463  
  1464      These parenthesized literals followed by a colon look like the start of an arrow function expression followed by a TypeScript return type (e.g. `([]) : 1` could be the start of the TypeScript arrow function `([]): 1 => 1`). Unlike in JavaScript, parsing arrow functions in TypeScript requires backtracking. In this case esbuild correctly determined that this expression wasn't an arrow function after all but the check for destructuring was incorrectly not covered under the backtracking process. With this release, the error message is now only reported if the parser successfully parses an arrow function without backtracking.
  1465  
  1466  * Fix generated TypeScript `enum` comments containing `*/` ([#2369](https://github.com/evanw/esbuild/issues/2369), [#2371](https://github.com/evanw/esbuild/pull/2371))
  1467  
  1468      TypeScript `enum` values that are equal to a number or string literal are inlined (references to the enum are replaced with the literal value) and have a `/* ... */` comment after them with the original enum name to improve readability. However, this comment is omitted if the enum name contains the character sequence `*/` because that would end the comment early and cause a syntax error:
  1469  
  1470      ```ts
  1471      // Original TypeScript
  1472      enum Foo { '/*' = 1, '*/' = 2 }
  1473      console.log(Foo['/*'], Foo['*/'])
  1474  
  1475      // Generated JavaScript
  1476      console.log(1 /* /* */, 2);
  1477      ```
  1478  
  1479      This was originally handled correctly when TypeScript `enum` inlining was initially implemented since it was only supported within a single file. However, when esbuild was later extended to support TypeScript `enum` inlining across files, this special case where the enum name contains `*/` was not handled in that new code. Starting with this release, esbuild will now handle enums with names containing `*/` correctly when they are inlined across files:
  1480  
  1481      ```ts
  1482      // foo.ts
  1483      export enum Foo { '/*' = 1, '*/' = 2 }
  1484  
  1485      // bar.ts
  1486      import { Foo } from './foo'
  1487      console.log(Foo['/*'], Foo['*/'])
  1488  
  1489      // Old output (with --bundle --format=esm)
  1490      console.log(1 /* /* */, 2 /* */ */);
  1491  
  1492      // New output (with --bundle --format=esm)
  1493      console.log(1 /* /* */, 2);
  1494      ```
  1495  
  1496      This fix was contributed by [@magic-akari](https://github.com/magic-akari).
  1497  
  1498  * Allow `declare` class fields to be initialized ([#2380](https://github.com/evanw/esbuild/issues/2380))
  1499  
  1500      This release fixes an oversight in the TypeScript parser that disallowed initializers for `declare` class fields. TypeScript actually allows the following limited initializer expressions for `readonly` fields:
  1501  
  1502      ```ts
  1503      declare const enum a { b = 0 }
  1504  
  1505      class Foo {
  1506        // These are allowed by TypeScript
  1507        declare readonly a = 0
  1508        declare readonly b = -0
  1509        declare readonly c = 0n
  1510        declare readonly d = -0n
  1511        declare readonly e = 'x'
  1512        declare readonly f = `x`
  1513        declare readonly g = a.b
  1514        declare readonly h = a['b']
  1515  
  1516        // These are not allowed by TypeScript
  1517        declare readonly x = (0)
  1518        declare readonly y = null
  1519        declare readonly z = -a.b
  1520      }
  1521      ```
  1522  
  1523      So with this release, esbuild now allows initializers for `declare` class fields too. To future-proof this in case TypeScript allows more expressions as initializers in the future (such as `null`), esbuild will allow any expression as an initializer and will leave the specifics of TypeScript's special-casing here to the TypeScript type checker.
  1524  
  1525  * Fix a bug in esbuild's feature compatibility table generator ([#2365](https://github.com/evanw/esbuild/issues/2365))
  1526  
  1527      Passing specific JavaScript engines to esbuild's `--target` flag restricts esbuild to only using JavaScript features that are supported on those engines in the output files that esbuild generates. The data for this feature is automatically derived from this compatibility table with a script: https://kangax.github.io/compat-table/.
  1528  
  1529      However, the script had a bug that could incorrectly consider a JavaScript syntax feature to be supported in a given engine even when it doesn't actually work in that engine. Specifically this bug happened when a certain aspect of JavaScript syntax has always worked incorrectly in that engine and the bug in that engine has never been fixed. This situation hasn't really come up before because previously esbuild pretty much only targeted JavaScript engines that always fix their bugs, but the two new JavaScript engines that were added in the previous release ([Hermes](https://hermesengine.dev/) and [Rhino](https://github.com/mozilla/rhino)) have many aspects of the JavaScript specification that have never been implemented, and may never be implemented. For example, the `let` and `const` keywords are not implemented correctly in those engines.
  1530  
  1531      With this release, esbuild's compatibility table generator script has been fixed and as a result, esbuild will now correctly consider a JavaScript syntax feature to be unsupported in a given engine if there is some aspect of that syntax that is broken in all known versions of that engine. This means that the following JavaScript syntax features are no longer considered to be supported by these engines (represented using esbuild's internal names for these syntax features):
  1532  
  1533      Hermes:
  1534      - `arrow`
  1535      - `const-and-let`
  1536      - `default-argument`
  1537      - `generator`
  1538      - `optional-catch-binding`
  1539      - `optional-chain`
  1540      - `rest-argument`
  1541      - `template-literal`
  1542  
  1543      Rhino:
  1544      - `arrow`
  1545      - `const-and-let`
  1546      - `destructuring`
  1547      - `for-of`
  1548      - `generator`
  1549      - `object-extensions`
  1550      - `template-literal`
  1551  
  1552      IE:
  1553      - `const-and-let`
  1554  
  1555  ## 0.14.48
  1556  
  1557  * Enable using esbuild in Deno via WebAssembly ([#2323](https://github.com/evanw/esbuild/issues/2323))
  1558  
  1559      The native implementation of esbuild is much faster than the WebAssembly version, but some people don't want to give Deno the `--allow-run` permission necessary to run esbuild and are ok waiting longer for their builds to finish when using the WebAssembly backend. With this release, you can now use esbuild via WebAssembly in Deno. To do this you will need to import from `wasm.js` instead of `mod.js`:
  1560  
  1561      ```js
  1562      import * as esbuild from 'https://deno.land/x/esbuild@v0.14.48/wasm.js'
  1563      const ts = 'let test: boolean = true'
  1564      const result = await esbuild.transform(ts, { loader: 'ts' })
  1565      console.log('result:', result)
  1566      ```
  1567  
  1568      Make sure you run Deno with `--allow-net` so esbuild can download the WebAssembly module. Using esbuild like this starts up a worker thread that runs esbuild in parallel (unless you call `esbuild.initialize({ worker: false })` to tell esbuild to run on the main thread). If you want to, you can call `esbuild.stop()` to terminate the worker if you won't be using esbuild anymore and you want to reclaim the memory.
  1569  
  1570      Note that Deno appears to have a bug where background WebAssembly optimization can prevent the process from exiting for many seconds. If you are trying to use Deno and WebAssembly to run esbuild quickly, you may need to manually call `Deno.exit(0)` after your code has finished running.
  1571  
  1572  * Add support for font file MIME types ([#2337](https://github.com/evanw/esbuild/issues/2337))
  1573  
  1574      This release adds support for font file MIME types to esbuild, which means they are now recognized by the built-in local web server and they are now used when a font file is loaded using the `dataurl` loader. The full set of newly-added file extension MIME type mappings is as follows:
  1575  
  1576      * `.eot` => `application/vnd.ms-fontobject`
  1577      * `.otf` => `font/otf`
  1578      * `.sfnt` => `font/sfnt`
  1579      * `.ttf` => `font/ttf`
  1580      * `.woff` => `font/woff`
  1581      * `.woff2` => `font/woff2`
  1582  
  1583  * Remove `"use strict";` when targeting ESM ([#2347](https://github.com/evanw/esbuild/issues/2347))
  1584  
  1585      All ES module code is automatically in strict mode, so a `"use strict";` directive is unnecessary. With this release, esbuild will now remove the `"use strict";` directive if the output format is ESM. This change makes the generated output file a few bytes smaller:
  1586  
  1587      ```js
  1588      // Original code
  1589      'use strict'
  1590      export let foo = 123
  1591  
  1592      // Old output (with --format=esm --minify)
  1593      "use strict";let t=123;export{t as foo};
  1594  
  1595      // New output (with --format=esm --minify)
  1596      let t=123;export{t as foo};
  1597      ```
  1598  
  1599  * Attempt to have esbuild work with Deno on FreeBSD ([#2356](https://github.com/evanw/esbuild/issues/2356))
  1600  
  1601      Deno doesn't support FreeBSD, but it's possible to build Deno for FreeBSD with some additional patches on top. This release of esbuild changes esbuild's Deno installer to download esbuild's FreeBSD binary in this situation. This configuration is unsupported although in theory everything should work.
  1602  
  1603  * Add some more target JavaScript engines ([#2357](https://github.com/evanw/esbuild/issues/2357))
  1604  
  1605      This release adds the [Rhino](https://github.com/mozilla/rhino) and [Hermes](https://hermesengine.dev/) JavaScript engines to the set of engine identifiers that can be passed to the `--target` flag. You can use this to restrict esbuild to only using JavaScript features that are supported on those engines in the output files that esbuild generates.
  1606  
  1607  ## 0.14.47
  1608  
  1609  * Make global names more compact when `||=` is available ([#2331](https://github.com/evanw/esbuild/issues/2331))
  1610  
  1611      With this release, the code esbuild generates for the `--global-name=` setting is now slightly shorter when you don't configure esbuild such that the `||=` operator is unsupported (e.g. with `--target=chrome80` or `--supported:logical-assignment=false`):
  1612  
  1613      ```js
  1614      // Original code
  1615      exports.foo = 123
  1616  
  1617      // Old output (with --format=iife --global-name=foo.bar.baz --minify)
  1618      var foo=foo||{};foo.bar=foo.bar||{};foo.bar.baz=(()=>{var b=(a,o)=>()=>(o||a((o={exports:{}}).exports,o),o.exports);var c=b(f=>{f.foo=123});return c();})();
  1619  
  1620      // New output (with --format=iife --global-name=foo.bar.baz --minify)
  1621      var foo;((foo||={}).bar||={}).baz=(()=>{var b=(a,o)=>()=>(o||a((o={exports:{}}).exports,o),o.exports);var c=b(f=>{f.foo=123});return c();})();
  1622      ```
  1623  
  1624  * Fix `--mangle-quoted=false` with `--minify-syntax=true`
  1625  
  1626      If property mangling is active and `--mangle-quoted` is disabled, quoted properties are supposed to be preserved. However, there was a case when this didn't happen if `--minify-syntax` was enabled, since that internally transforms `x['y']` into `x.y` to reduce code size. This issue has been fixed:
  1627  
  1628      ```js
  1629      // Original code
  1630      x.foo = x['bar'] = { foo: y, 'bar': z }
  1631  
  1632      // Old output (with --mangle-props=. --mangle-quoted=false --minify-syntax=true)
  1633      x.a = x.b = { a: y, bar: z };
  1634  
  1635      // New output (with --mangle-props=. --mangle-quoted=false --minify-syntax=true)
  1636      x.a = x.bar = { a: y, bar: z };
  1637      ```
  1638  
  1639      Notice how the property `foo` is always used unquoted but the property `bar` is always used quoted, so `foo` should be consistently mangled while `bar` should be consistently not mangled.
  1640  
  1641  * Fix a minification bug regarding `this` and property initializers
  1642  
  1643      When minification is enabled, esbuild attempts to inline the initializers of variables that have only been used once into the start of the following expression to reduce code size. However, there was a bug where this transformation could change the value of `this` when the initializer is a property access and the start of the following expression is a call expression. This release fixes the bug:
  1644  
  1645      ```js
  1646      // Original code
  1647      function foo(obj) {
  1648        let fn = obj.prop;
  1649        fn();
  1650      }
  1651  
  1652      // Old output (with --minify)
  1653      function foo(f){f.prop()}
  1654  
  1655      // New output (with --minify)
  1656      function foo(o){let f=o.prop;f()}
  1657      ```
  1658  
  1659  ## 0.14.46
  1660  
  1661  * Add the ability to override support for individual syntax features ([#2060](https://github.com/evanw/esbuild/issues/2060), [#2290](https://github.com/evanw/esbuild/issues/2290), [#2308](https://github.com/evanw/esbuild/issues/2308))
  1662  
  1663      The `target` setting already lets you configure esbuild to restrict its output by only making use of syntax features that are known to be supported in the configured target environment. For example, setting `target` to `chrome50` causes esbuild to automatically transform optional chain expressions into the equivalent older JavaScript and prevents you from using BigInts, among many other things. However, sometimes you may want to customize this set of unsupported syntax features at the individual feature level.
  1664  
  1665      Some examples of why you might want to do this:
  1666  
  1667      * JavaScript runtimes often do a quick implementation of newer syntax features that is slower than the equivalent older JavaScript, and you can get a speedup by telling esbuild to pretend this syntax feature isn't supported. For example, V8 has a [long-standing performance bug regarding object spread](https://bugs.chromium.org/p/v8/issues/detail?id=11536) that can be avoided by manually copying properties instead of using object spread syntax. Right now esbuild hard-codes this optimization if you set `target` to a V8-based runtime.
  1668  
  1669      * There are many less-used JavaScript runtimes in addition to the ones present in browsers, and these runtimes sometimes just decide not to implement parts of the specification, which might make sense for runtimes intended for embedded environments. For example, the developers behind Facebook's JavaScript runtime [Hermes](https://hermesengine.dev/) have decided to not implement classes despite it being a major JavaScript feature that was added seven years ago and that is used in virtually every large JavaScript project.
  1670  
  1671      * You may be processing esbuild's output with another tool, and you may want esbuild to transform certain features and the other tool to transform certain other features. For example, if you are using esbuild to transform files individually to ES5 but you are then feeding the output into Webpack for bundling, you may want to preserve `import()` expressions even though they are a syntax error in ES5.
  1672  
  1673      With this release, you can now use `--supported:feature=false` to force `feature` to be unsupported. This will cause esbuild to either rewrite code that uses the feature into older code that doesn't use the feature (if esbuild is able to), or to emit a build error (if esbuild is unable to). For example, you can use `--supported:arrow=false` to turn arrow functions into function expressions and `--supported:bigint=false` to make it an error to use a BigInt literal. You can also use `--supported:feature=true` to force it to be supported, which means esbuild will pass it through without transforming it. Keep in mind that this is an advanced feature. For most use cases you will probably want to just use `target` instead of using this.
  1674  
  1675      The full set of currently-allowed features are as follows:
  1676  
  1677      **JavaScript:**
  1678      * `arbitrary-module-namespace-names`
  1679      * `array-spread`
  1680      * `arrow`
  1681      * `async-await`
  1682      * `async-generator`
  1683      * `bigint`
  1684      * `class`
  1685      * `class-field`
  1686      * `class-private-accessor`
  1687      * `class-private-brand-check`
  1688      * `class-private-field`
  1689      * `class-private-method`
  1690      * `class-private-static-accessor`
  1691      * `class-private-static-field`
  1692      * `class-private-static-method`
  1693      * `class-static-blocks`
  1694      * `class-static-field`
  1695      * `const-and-let`
  1696      * `default-argument`
  1697      * `destructuring`
  1698      * `dynamic-import`
  1699      * `exponent-operator`
  1700      * `export-star-as`
  1701      * `for-await`
  1702      * `for-of`
  1703      * `generator`
  1704      * `hashbang`
  1705      * `import-assertions`
  1706      * `import-meta`
  1707      * `logical-assignment`
  1708      * `nested-rest-binding`
  1709      * `new-target`
  1710      * `node-colon-prefix-import`
  1711      * `node-colon-prefix-require`
  1712      * `nullish-coalescing`
  1713      * `object-accessors`
  1714      * `object-extensions`
  1715      * `object-rest-spread`
  1716      * `optional-catch-binding`
  1717      * `optional-chain`
  1718      * `regexp-dot-all-flag`
  1719      * `regexp-lookbehind-assertions`
  1720      * `regexp-match-indices`
  1721      * `regexp-named-capture-groups`
  1722      * `regexp-sticky-and-unicode-flags`
  1723      * `regexp-unicode-property-escapes`
  1724      * `rest-argument`
  1725      * `template-literal`
  1726      * `top-level-await`
  1727      * `typeof-exotic-object-is-object`
  1728      * `unicode-escapes`
  1729  
  1730      **CSS:**
  1731      * `hex-rgba`
  1732      * `rebecca-purple`
  1733      * `modern-rgb-hsl`
  1734      * `inset-property`
  1735      * `nesting`
  1736  
  1737      Since you can now specify `--supported:object-rest-spread=false` yourself to work around the V8 performance issue mentioned above, esbuild will no longer automatically transform all instances of object spread when targeting a V8-based JavaScript runtime going forward.
  1738  
  1739      _Note that JavaScript feature transformation is very complex and allowing full customization of the set of supported syntax features could cause bugs in esbuild due to new interactions between multiple features that were never possible before. Consider this to be an experimental feature._
  1740  
  1741  * Implement `extends` constraints on `infer` type variables ([#2330](https://github.com/evanw/esbuild/issues/2330))
  1742  
  1743      TypeScript 4.7 introduced the ability to write an `extends` constraint after an `infer` type variable, which looks like this:
  1744  
  1745      ```ts
  1746      type FirstIfString<T> =
  1747        T extends [infer S extends string, ...unknown[]]
  1748          ? S
  1749          : never;
  1750      ```
  1751  
  1752      You can read the blog post for more details: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables. Previously this was a syntax error in esbuild but with this release, esbuild can now parse this syntax correctly.
  1753  
  1754  * Allow `define` to match optional chain expressions ([#2324](https://github.com/evanw/esbuild/issues/2324))
  1755  
  1756      Previously esbuild's `define` feature only matched member expressions that did not use optional chaining. With this release, esbuild will now also match those that use optional chaining:
  1757  
  1758      ```js
  1759      // Original code
  1760      console.log(a.b, a?.b)
  1761  
  1762      // Old output (with --define:a.b=c)
  1763      console.log(c, a?.b);
  1764  
  1765      // New output (with --define:a.b=c)
  1766      console.log(c, c);
  1767      ```
  1768  
  1769      This is for compatibility with Webpack's [`DefinePlugin`](https://webpack.js.org/plugins/define-plugin/), which behaves the same way.
  1770  
  1771  ## 0.14.45
  1772  
  1773  * Add a log message for ambiguous re-exports ([#2322](https://github.com/evanw/esbuild/issues/2322))
  1774  
  1775      In JavaScript, you can re-export symbols from another file using `export * from './another-file'`. When you do this from multiple files that export different symbols with the same name, this creates an ambiguous export which is causes that name to not be exported. This is harmless if you don't plan on using the ambiguous export name, so esbuild doesn't have a warning for this. But if you do want a warning for this (or if you want to make it an error), you can now opt-in to seeing this log message with `--log-override:ambiguous-reexport=warning` or `--log-override:ambiguous-reexport=error`. The log message looks like this:
  1776  
  1777      ```
  1778      ▲ [WARNING] Re-export of "common" in "example.js" is ambiguous and has been removed [ambiguous-reexport]
  1779  
  1780        One definition of "common" comes from "a.js" here:
  1781  
  1782          a.js:2:11:
  1783            2 │ export let common = 2
  1784              ╵            ~~~~~~
  1785  
  1786        Another definition of "common" comes from "b.js" here:
  1787  
  1788          b.js:3:14:
  1789            3 │ export { b as common }
  1790              ╵               ~~~~~~
  1791      ```
  1792  
  1793  * Optimize the output of the JSON loader ([#2161](https://github.com/evanw/esbuild/issues/2161))
  1794  
  1795      The `json` loader (which is enabled by default for `.json` files) parses the file as JSON and generates a JavaScript file with the parsed expression as the `default` export. This behavior is standard and works in both node and the browser (well, as long as you use an [import assertion](https://v8.dev/features/import-assertions)). As an extension, esbuild also allows you to import additional top-level properties of the JSON object directly as a named export. This is beneficial for tree shaking. For example:
  1796  
  1797      ```js
  1798      import { version } from 'esbuild/package.json'
  1799      console.log(version)
  1800      ```
  1801  
  1802      If you bundle the above code with esbuild, you'll get something like the following:
  1803  
  1804      ```js
  1805      // node_modules/esbuild/package.json
  1806      var version = "0.14.44";
  1807  
  1808      // example.js
  1809      console.log(version);
  1810      ```
  1811  
  1812      Most of the `package.json` file is irrelevant and has been omitted from the output due to tree shaking. The way esbuild implements this is to have the JavaScript file that's generated from the JSON look something like this with a separate exported variable for each property on the top-level object:
  1813  
  1814      ```js
  1815      // node_modules/esbuild/package.json
  1816      export var name = "esbuild";
  1817      export var version = "0.14.44";
  1818      export var repository = "https://github.com/evanw/esbuild";
  1819      export var bin = {
  1820        esbuild: "bin/esbuild"
  1821      };
  1822      ...
  1823      export default {
  1824        name,
  1825        version,
  1826        repository,
  1827        bin,
  1828        ...
  1829      };
  1830      ```
  1831  
  1832      However, this means that if you import the `default` export instead of a named export, you will get non-optimal output. The `default` export references all top-level properties, leading to many unnecessary variables in the output. With this release esbuild will now optimize this case to only generate additional variables for top-level object properties that are actually imported:
  1833  
  1834      ```js
  1835      // Original code
  1836      import all, { bar } from 'data:application/json,{"foo":[1,2,3],"bar":[4,5,6]}'
  1837      console.log(all, bar)
  1838  
  1839      // Old output (with --bundle --minify --format=esm)
  1840      var a=[1,2,3],l=[4,5,6],r={foo:a,bar:l};console.log(r,l);
  1841  
  1842      // New output (with --bundle --minify --format=esm)
  1843      var l=[4,5,6],r={foo:[1,2,3],bar:l};console.log(r,l);
  1844      ```
  1845  
  1846      Notice how there is no longer an unnecessary generated variable for `foo` since it's never imported. And if you only import the `default` export, esbuild will now reproduce the original JSON object in the output with all top-level properties compactly inline.
  1847  
  1848  * Add `id` to warnings returned from the API
  1849  
  1850      With this release, warnings returned from esbuild's API now have an `id` property. This identifies which kind of log message it is, which can be used to more easily filter out certain warnings. For example, reassigning a `const` variable will generate a message with an `id` of `"assign-to-constant"`. This also gives you the identifier you need to apply a log override for that kind of message: https://esbuild.github.io/api/#log-override.
  1851  
  1852  ## 0.14.44
  1853  
  1854  * Add a `copy` loader ([#2255](https://github.com/evanw/esbuild/issues/2255))
  1855  
  1856      You can configure the "loader" for a specific file extension in esbuild, which is a way of telling esbuild how it should treat that file. For example, the `text` loader means the file is imported as a string while the `binary` loader means the file is imported as a `Uint8Array`. If you want the imported file to stay a separate file, the only option was previously the `file` loader (which is intended to be similar to Webpack's [`file-loader`](https://v4.webpack.js.org/loaders/file-loader/) package). This loader copies the file to the output directory and imports the path to that output file as a string. This is useful for a web application because you can refer to resources such as `.png` images by importing them for their URL. However, it's not helpful if you need the imported file to stay a separate file but to still behave the way it normally would when the code is run without bundling.
  1857  
  1858      With this release, there is now a new loader called `copy` that copies the loaded file to the output directory and then rewrites the path of the import statement or `require()` call to point to the copied file instead of the original file. This will automatically add a content hash to the output name by default (which can be configured with the `--asset-names=` setting). You can use this by specifying `copy` for a specific file extension, such as with `--loader:.png=copy`.
  1859  
  1860  * Fix a regression in arrow function lowering ([#2302](https://github.com/evanw/esbuild/pull/2302))
  1861  
  1862      This release fixes a regression with lowering arrow functions to function expressions in ES5. This feature was introduced in version 0.7.2 and regressed in version 0.14.30.
  1863  
  1864      In JavaScript, regular `function` expressions treat `this` as an implicit argument that is determined by how the function is called, but arrow functions treat `this` as a variable that is captured in the closure from the surrounding lexical scope. This is emulated in esbuild by storing the value of `this` in a variable before changing the arrow function into a function expression.
  1865  
  1866      However, the code that did this didn't treat `this` expressions as a usage of that generated variable. Version 0.14.30 began omitting unused generated variables, which caused the transformation of `this` to break. This regression happened due to missing test coverage. With this release, the problem has been fixed:
  1867  
  1868      ```js
  1869      // Original code
  1870      function foo() {
  1871        return () => this
  1872      }
  1873  
  1874      // Old output (with --target=es5)
  1875      function foo() {
  1876        return function() {
  1877          return _this;
  1878        };
  1879      }
  1880  
  1881      // New output (with --target=es5)
  1882      function foo() {
  1883        var _this = this;
  1884        return function() {
  1885          return _this;
  1886        };
  1887      }
  1888      ```
  1889  
  1890      This fix was contributed by [@nkeynes](https://github.com/nkeynes).
  1891  
  1892  * Allow entity names as define values ([#2292](https://github.com/evanw/esbuild/issues/2292))
  1893  
  1894      The "define" feature allows you to replace certain expressions with certain other expressions at compile time. For example, you might want to replace the global identifier `IS_PRODUCTION` with the boolean value `true` when building for production. Previously the only expressions you could substitute in were either identifier expressions or anything that is valid JSON syntax. This limitation exists because supporting more complex expressions is more complex (for example, substituting in a `require()` call could potentially pull in additional files, which would need to be handled). With this release, you can now also now define something as a member expression chain of the form `foo.abc.xyz`.
  1895  
  1896  * Implement package self-references ([#2312](https://github.com/evanw/esbuild/issues/2312))
  1897  
  1898      This release implements a rarely-used feature in node where a package can import itself by name instead of using relative imports. You can read more about this feature here: https://nodejs.org/api/packages.html#self-referencing-a-package-using-its-name. For example, assuming the `package.json` in a given package looks like this:
  1899  
  1900      ```json
  1901      // package.json
  1902      {
  1903        "name": "a-package",
  1904        "exports": {
  1905          ".": "./main.mjs",
  1906          "./foo": "./foo.js"
  1907        }
  1908      }
  1909      ```
  1910  
  1911      Then any module in that package can reference an export in the package itself:
  1912  
  1913      ```js
  1914      // ./a-module.mjs
  1915      import { something } from 'a-package'; // Imports "something" from ./main.mjs.
  1916      ```
  1917  
  1918      Self-referencing is also available when using `require`, both in an ES module, and in a CommonJS one. For example, this code will also work:
  1919  
  1920      ```js
  1921      // ./a-module.js
  1922      const { something } = require('a-package/foo'); // Loads from ./foo.js.
  1923      ```
  1924  
  1925  * Add a warning for assigning to an import ([#2319](https://github.com/evanw/esbuild/issues/2319))
  1926  
  1927      Import bindings are immutable in JavaScript, and assigning to them will throw an error. So instead of doing this:
  1928  
  1929      ```js
  1930      import { foo } from 'foo'
  1931      foo++
  1932      ```
  1933  
  1934      You need to do something like this instead:
  1935  
  1936      ```js
  1937      import { foo, setFoo } from 'foo'
  1938      setFoo(foo + 1)
  1939      ```
  1940  
  1941      This is already an error if you try to bundle this code with esbuild. However, this was previously allowed silently when bundling is disabled, which can lead to confusion for people who don't know about this aspect of how JavaScript works. So with this release, there is now a warning when you do this:
  1942  
  1943      ```
  1944      ▲ [WARNING] This assignment will throw because "foo" is an import [assign-to-import]
  1945  
  1946          example.js:2:0:
  1947            2 │ foo++
  1948              ╵ ~~~
  1949  
  1950        Imports are immutable in JavaScript. To modify the value of this import, you must export a setter
  1951        function in the imported file (e.g. "setFoo") and then import and call that function here instead.
  1952      ```
  1953  
  1954      This new warning can be turned off with `--log-override:assign-to-import=silent` if you don't want to see it.
  1955  
  1956  * Implement `alwaysStrict` in `tsconfig.json` ([#2264](https://github.com/evanw/esbuild/issues/2264))
  1957  
  1958      This release adds `alwaysStrict` to the set of TypeScript `tsconfig.json` configuration values that esbuild supports. When this is enabled, esbuild will forbid syntax that isn't allowed in strict mode and will automatically insert `"use strict";` at the top of generated output files. This matches the behavior of the TypeScript compiler: https://www.typescriptlang.org/tsconfig#alwaysStrict.
  1959  
  1960  ## 0.14.43
  1961  
  1962  * Fix TypeScript parse error whe a generic function is the first type argument ([#2306](https://github.com/evanw/esbuild/issues/2306))
  1963  
  1964      In TypeScript, the `<<` token may need to be split apart into two `<` tokens if it's present in a type argument context. This was already correctly handled for all type expressions and for identifier expressions such as in the following code:
  1965  
  1966      ```ts
  1967      // These cases already worked in the previous release
  1968      let foo: Array<<T>() => T>;
  1969      bar<<T>() => T>;
  1970      ```
  1971  
  1972      However, normal expressions of the following form were previously incorrectly treated as syntax errors:
  1973  
  1974      ```ts
  1975      // These cases were broken but have now been fixed
  1976      foo.bar<<T>() => T>;
  1977      foo?.<<T>() => T>();
  1978      ```
  1979  
  1980      With this release, these cases now parsed correctly.
  1981  
  1982  * Fix minification regression with pure IIFEs ([#2279](https://github.com/evanw/esbuild/issues/2279))
  1983  
  1984      An Immediately Invoked Function Expression (IIFE) is a function call to an anonymous function, and is a way of introducing a new function-level scope in JavaScript since JavaScript lacks a way to do this otherwise. And a pure function call is a function call with the special `/* @__PURE__ */` comment before it, which tells JavaScript build tools that the function call can be considered to have no side effects (and can be removed if it's unused).
  1985  
  1986      Version 0.14.9 of esbuild introduced a regression that changed esbuild's behavior when these two features were combined. If the IIFE body contains a single expression, the resulting output still contained that expression instead of being empty. This is a minor regression because you normally wouldn't write code like this, so this shouldn't come up in practice, and it doesn't cause any correctness issues (just larger-than-necessary output). It's unusual that you would tell esbuild "remove this if the result is unused" and then not store the result anywhere, since the result is unused by construction. But regardless, the issue has now been fixed.
  1987  
  1988      For example, the following code is a pure IIFE, which means it should be completely removed when minification is enabled. Previously it was replaced by the contents of the IIFE but it's now completely removed:
  1989  
  1990      ```js
  1991      // Original code
  1992      /* @__PURE__ */ (() => console.log(1))()
  1993  
  1994      // Old output (with --minify)
  1995      console.log(1);
  1996  
  1997      // New output (with --minify)
  1998      ```
  1999  
  2000  * Add log messages for indirect `require` references ([#2231](https://github.com/evanw/esbuild/issues/2231))
  2001  
  2002      A long time ago esbuild used to warn about indirect uses of `require` because they break esbuild's ability to analyze the dependencies of the code and cause dependencies to not be bundled, resulting in a potentially broken bundle. However, this warning was removed because many people wanted the warning to be removed. Some packages have code that uses `require` like this but on a code path that isn't used at run-time, so their code still happens to work even though the bundle is incomplete. For example, the following code will _not_ bundle `bindings`:
  2003  
  2004      ```js
  2005      // Prevent React Native packager from seeing modules required with this
  2006      const nodeRequire = require;
  2007  
  2008      function getRealmConstructor(environment) {
  2009        switch (environment) {
  2010          case "node.js":
  2011          case "electron":
  2012            return nodeRequire("bindings")("realm.node").Realm;
  2013        }
  2014      }
  2015      ```
  2016  
  2017      Version 0.11.11 of esbuild removed this warning, which means people no longer have a way to know at compile time whether their bundle is broken in this way. Now that esbuild has custom log message levels, this warning can be added back in a way that should make both people happy. With this release, there is now a log message for this that defaults to the `debug` log level, which normally isn't visible. You can either do `--log-override:indirect-require=warning` to make this log message a warning (and therefore visible) or use `--log-level=debug` to see this and all other `debug` log messages.
  2018  
  2019  ## 0.14.42
  2020  
  2021  * Fix a parser hang on invalid CSS ([#2276](https://github.com/evanw/esbuild/issues/2276))
  2022  
  2023      Previously invalid CSS with unbalanced parentheses could cause esbuild's CSS parser to hang. An example of such an input is the CSS file `:x(`. This hang has been fixed.
  2024  
  2025  * Add support for custom log message levels
  2026  
  2027      This release allows you to override the default log level of esbuild's individual log messages. For example, CSS syntax errors are treated as warnings instead of errors by default because CSS grammar allows for rules containing syntax errors to be ignored. However, if you would like for esbuild to consider CSS syntax errors to be build errors, you can now configure that like this:
  2028  
  2029      * CLI
  2030  
  2031          ```sh
  2032          $ esbuild example.css --log-override:css-syntax-error=error
  2033          ```
  2034  
  2035      * JS API
  2036  
  2037          ```js
  2038          let result = await esbuild.build({
  2039            entryPoints: ['example.css'],
  2040            logOverride: {
  2041              'css-syntax-error': 'error',
  2042            },
  2043          })
  2044          ```
  2045  
  2046      * Go API
  2047  
  2048          ```go
  2049          result := api.Build(api.BuildOptions{
  2050            EntryPoints: []string{"example.ts"},
  2051            LogOverride: map[string]api.LogLevel{
  2052              "css-syntax-error": api.LogLevelError,
  2053            },
  2054          })
  2055          ```
  2056  
  2057      You can also now use this feature to silence warnings that you are not interested in. Log messages are referred to by their identifier. Each identifier is stable (i.e. shouldn't change over time) except there is no guarantee that the log message will continue to exist. A given log message may potentially be removed in the future, in which case esbuild will ignore log levels set for that identifier. The current list of supported log level identifiers for use with this feature can be found below:
  2058  
  2059      **JavaScript:**
  2060      * `assign-to-constant`
  2061      * `call-import-namespace`
  2062      * `commonjs-variable-in-esm`
  2063      * `delete-super-property`
  2064      * `direct-eval`
  2065      * `duplicate-case`
  2066      * `duplicate-object-key`
  2067      * `empty-import-meta`
  2068      * `equals-nan`
  2069      * `equals-negative-zero`
  2070      * `equals-new-object`
  2071      * `html-comment-in-js`
  2072      * `impossible-typeof`
  2073      * `private-name-will-throw`
  2074      * `semicolon-after-return`
  2075      * `suspicious-boolean-not`
  2076      * `this-is-undefined-in-esm`
  2077      * `unsupported-dynamic-import`
  2078      * `unsupported-jsx-comment`
  2079      * `unsupported-regexp`
  2080      * `unsupported-require-call`
  2081  
  2082      **CSS:**
  2083      * `css-syntax-error`
  2084      * `invalid-@charset`
  2085      * `invalid-@import`
  2086      * `invalid-@nest`
  2087      * `invalid-@layer`
  2088      * `invalid-calc`
  2089      * `js-comment-in-css`
  2090      * `unsupported-@charset`
  2091      * `unsupported-@namespace`
  2092      * `unsupported-css-property`
  2093  
  2094      **Bundler:**
  2095      * `different-path-case`
  2096      * `ignored-bare-import`
  2097      * `ignored-dynamic-import`
  2098      * `import-is-undefined`
  2099      * `package.json`
  2100      * `require-resolve-not-external`
  2101      * `tsconfig.json`
  2102  
  2103      **Source maps:**
  2104      * `invalid-source-mappings`
  2105      * `sections-in-source-map`
  2106      * `missing-source-map`
  2107      * `unsupported-source-map-comment`
  2108  
  2109      Documentation about which identifiers correspond to which log messages will be added in the future, but hasn't been written yet. Note that it's not possible to configure the log level for a build error. This is by design because changing that would cause esbuild to incorrectly proceed in the building process generate invalid build output. You can only configure the log level for non-error log messages (although you can turn non-errors into errors).
  2110  
  2111  ## 0.14.41
  2112  
  2113  * Fix a minification regression in 0.14.40 ([#2270](https://github.com/evanw/esbuild/issues/2270), [#2271](https://github.com/evanw/esbuild/issues/2271), [#2273](https://github.com/evanw/esbuild/pull/2273))
  2114  
  2115      Version 0.14.40 substituted string property keys with numeric property keys if the number has the same string representation as the original string. This was done in three places: computed member expressions, object literal properties, and class fields. However, negative numbers are only valid in computed member expressions while esbuild incorrectly applied this substitution for negative numbers in all places. This release fixes the regression by only doing this substitution for negative numbers in computed member expressions.
  2116  
  2117      This fix was contributed by [@susiwen8](https://github.com/susiwen8).
  2118  
  2119  ## 0.14.40
  2120  
  2121  * Correct esbuild's implementation of `"preserveValueImports": true` ([#2268](https://github.com/evanw/esbuild/issues/2268))
  2122  
  2123      TypeScript's [`preserveValueImports` setting](https://www.typescriptlang.org/tsconfig#preserveValueImports) tells the compiler to preserve unused imports, which can sometimes be necessary because otherwise TypeScript will remove unused imports as it assumes they are type annotations. This setting is useful for programming environments that strip TypeScript types as part of a larger code transformation where additional code is appended later that will then make use of those unused imports, such as with [Svelte](https://svelte.dev/) or [Vue](https://vuejs.org/).
  2124  
  2125      This release fixes an issue where esbuild's implementation of `preserveValueImports` diverged from the official TypeScript compiler. If the import clause is present but empty of values (even if it contains types), then the import clause should be considered a type-only import clause. This was an oversight, and has now been fixed:
  2126  
  2127      ```ts
  2128      // Original code
  2129      import "keep"
  2130      import { k1 } from "keep"
  2131      import k2, { type t1 } from "keep"
  2132      import {} from "remove"
  2133      import { type t2 } from "remove"
  2134  
  2135      // Old output under "preserveValueImports": true
  2136      import "keep";
  2137      import { k1 } from "keep";
  2138      import k2, {} from "keep";
  2139      import {} from "remove";
  2140      import {} from "remove";
  2141  
  2142      // New output under "preserveValueImports": true (matches the TypeScript compiler)
  2143      import "keep";
  2144      import { k1 } from "keep";
  2145      import k2 from "keep";
  2146      ```
  2147  
  2148  * Avoid regular expression syntax errors in older browsers ([#2215](https://github.com/evanw/esbuild/issues/2215))
  2149  
  2150      Previously esbuild always passed JavaScript regular expression literals through unmodified from the input to the output. This is undesirable when the regular expression uses newer features that the configured target environment doesn't support. For example, the `d` flag (i.e. the [match indices feature](https://v8.dev/features/regexp-match-indices)) is new in ES2022 and doesn't work in older browsers. If esbuild generated a regular expression literal containing the `d` flag, then older browsers would consider esbuild's output to be a syntax error and none of the code would run.
  2151  
  2152      With this release, esbuild now detects when an unsupported feature is being used and converts the regular expression literal into a `new RegExp()` constructor instead. One consequence of this is that the syntax error is transformed into a run-time error, which allows the output code to run (and to potentially handle the run-time error). Another consequence of this is that it allows you to include a polyfill that overwrites the `RegExp` constructor in older browsers with one that supports modern features. Note that esbuild does not handle polyfills for you, so you will need to include a `RegExp` polyfill yourself if you want one.
  2153  
  2154      ```js
  2155      // Original code
  2156      console.log(/b/d.exec('abc').indices)
  2157  
  2158      // New output (with --target=chrome90)
  2159      console.log(/b/d.exec("abc").indices);
  2160  
  2161      // New output (with --target=chrome89)
  2162      console.log(new RegExp("b", "d").exec("abc").indices);
  2163      ```
  2164  
  2165      This is currently done transparently without a warning. If you would like to debug this transformation to see where in your code esbuild is transforming regular expression literals and why, you can pass `--log-level=debug` to esbuild and review the information present in esbuild's debug logs.
  2166  
  2167  * Add Opera to more internal feature compatibility tables ([#2247](https://github.com/evanw/esbuild/issues/2247), [#2252](https://github.com/evanw/esbuild/pull/2252))
  2168  
  2169      The internal compatibility tables that esbuild uses to determine which environments support which features are derived from multiple sources. Most of it is automatically derived from [these ECMAScript compatibility tables](https://kangax.github.io/compat-table/), but missing information is manually copied from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/), GitHub PR comments, and various other websites. Version 0.14.35 of esbuild introduced Opera as a possible target environment which was automatically picked up by the compatibility table script, but the manually-copied information wasn't updated to include Opera. This release fixes this omission so Opera feature compatibility should now be accurate.
  2170  
  2171      This was contributed by [@lbwa](https://github.com/lbwa).
  2172  
  2173  * Ignore `EPERM` errors on directories ([#2261](https://github.com/evanw/esbuild/issues/2261))
  2174  
  2175      Previously bundling with esbuild when inside a sandbox environment which does not have permission to access the parent directory 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 with running esbuild with `sandbox-exec` on macOS. With this release, esbuild will treat directories with permission failures as empty to allow for the `node_modules` search to continue past the denied directory and into its parent directory. This means it should now be possible to bundle with esbuild in these situations. This fix is similar to the fix in version 0.9.1 but is for `EPERM` while that fix was for `EACCES`.
  2176  
  2177  * Remove an irrelevant extra `"use strict"` directive ([#2264](https://github.com/evanw/esbuild/issues/2264))
  2178  
  2179      The presence of a `"use strict"` directive in the output file is controlled by the presence of one in the entry point. However, there was a bug that would include one twice if the output format is ESM. This bug has been fixed.
  2180  
  2181  * Minify strings into integers inside computed properties ([#2214](https://github.com/evanw/esbuild/issues/2214))
  2182  
  2183      This release now minifies `a["0"]` into `a[0]` when the result is equivalent:
  2184  
  2185      ```js
  2186      // Original code
  2187      console.log(x['0'], { '0': x }, class { '0' = x })
  2188  
  2189      // Old output (with --minify)
  2190      console.log(x["0"],{"0":x},class{"0"=x});
  2191  
  2192      // New output (with --minify)
  2193      console.log(x[0],{0:x},class{0=x});
  2194      ```
  2195  
  2196      This transformation currently only happens when the numeric property represents an integer within the signed 32-bit integer range.
  2197  
  2198  ## 0.14.39
  2199  
  2200  * Fix code generation for `export default` and `/* @__PURE__ */` call ([#2203](https://github.com/evanw/esbuild/issues/2203))
  2201  
  2202      The `/* @__PURE__ */` comment annotation can be added to function calls to indicate that they are side-effect free. These annotations are passed through into the output by esbuild since many JavaScript tools understand them. However, there was an edge case where printing this comment before a function call caused esbuild to fail to parenthesize a function literal because it thought it was no longer at the start of the expression. This problem has been fixed:
  2203  
  2204      ```js
  2205      // Original code
  2206      export default /* @__PURE__ */ (function() {
  2207      })()
  2208  
  2209      // Old output
  2210      export default /* @__PURE__ */ function() {
  2211      }();
  2212  
  2213      // New output
  2214      export default /* @__PURE__ */ (function() {
  2215      })();
  2216      ```
  2217  
  2218  * Preserve `...` before JSX child expressions ([#2245](https://github.com/evanw/esbuild/issues/2245))
  2219  
  2220      TypeScript 4.5 changed how JSX child expressions that start with `...` are emitted. Previously the `...` was omitted but starting with TypeScript 4.5, the `...` is now preserved instead. This release updates esbuild to match TypeScript's new output in this case:
  2221  
  2222      ```jsx
  2223      // Original code
  2224      console.log(<a>{...b}</a>)
  2225  
  2226      // Old output
  2227      console.log(/* @__PURE__ */ React.createElement("a", null, b));
  2228  
  2229      // New output
  2230      console.log(/* @__PURE__ */ React.createElement("a", null, ...b));
  2231      ```
  2232  
  2233      Note that this behavior is TypeScript-specific. Babel doesn't support the `...` token at all (it gives the error "Spread children are not supported in React").
  2234  
  2235  * Slightly adjust esbuild's handling of the `browser` field in `package.json` ([#2239](https://github.com/evanw/esbuild/issues/2239))
  2236  
  2237      This release changes esbuild's interpretation of `browser` path remapping to fix a regression that was introduced in esbuild version 0.14.21. Browserify has a bug where it incorrectly matches package paths to relative paths in the `browser` field, and esbuild replicates this bug for compatibility with Browserify. I have a set of tests that I use to verify that esbuild's replication of this Browserify is accurate here: https://github.com/evanw/package-json-browser-tests. However, I was missing a test case and esbuild's behavior diverges from Browserify in this case. This release now handles this edge case as well:
  2238  
  2239      * `entry.js`:
  2240  
  2241          ```js
  2242          require('pkg/sub')
  2243          ```
  2244  
  2245      * `node_modules/pkg/package.json`:
  2246  
  2247          ```json
  2248          {
  2249            "browser": {
  2250              "./sub": "./sub/foo.js",
  2251              "./sub/sub.js": "./sub/foo.js"
  2252            }
  2253          }
  2254          ```
  2255  
  2256      * `node_modules/pkg/sub/foo.js`:
  2257  
  2258          ```js
  2259          require('sub')
  2260          ```
  2261  
  2262      * `node_modules/sub/index.js`:
  2263  
  2264          ```js
  2265          console.log('works')
  2266          ```
  2267  
  2268      The import path `sub` in `require('sub')` was previously matching the remapping `"./sub/sub.js": "./sub/foo.js"` but with this release it should now no longer match that remapping. Now `require('sub')` will only match the remapping `"./sub/sub": "./sub/foo.js"` (without the trailing `.js`). Browserify apparently only matches without the `.js` suffix here.
  2269  
  2270  ## 0.14.38
  2271  
  2272  * Further fixes to TypeScript 4.7 instantiation expression parsing ([#2201](https://github.com/evanw/esbuild/issues/2201))
  2273  
  2274      This release fixes some additional edge cases with parsing instantiation expressions from the upcoming version 4.7 of TypeScript. Previously it was allowed for an instantiation expression to precede a binary operator but with this release, that's no longer allowed. This was sometimes valid in the TypeScript 4.7 beta but is no longer allowed in the latest version of TypeScript 4.7. Fixing this also fixed a regression that was introduced by the previous release of esbuild:
  2275  
  2276      | Code           | TS 4.6.3     | TS 4.7.0 beta | TS 4.7.0 nightly | esbuild 0.14.36 | esbuild 0.14.37 | esbuild 0.14.38 |
  2277      |----------------|--------------|---------------|------------------|-----------------|-----------------|-----------------|
  2278      | `a<b> == c<d>` | Invalid      | `a == c`      | Invalid          | `a == c`        | `a == c`        | Invalid         |
  2279      | `a<b> in c<d>` | Invalid      | Invalid       | Invalid          | Invalid         | `a in c`        | Invalid         |
  2280      | `a<b>>=c<d>`   | Invalid      | Invalid       | Invalid          | Invalid         | `a >= c`        | Invalid         |
  2281      | `a<b>=c<d>`    | Invalid      | `a < b >= c`  | `a = c`          | `a < b >= c`    | `a = c`         | `a = c`         |
  2282      | `a<b>>c<d>`    | `a < b >> c` | `a < b >> c`  | `a < b >> c`     | `a < b >> c`    | `a > c`         | `a < b >> c`    |
  2283  
  2284      This table illustrates some of the more significant changes between all of these parsers. The most important part is that esbuild 0.14.38 now matches the behavior of the latest TypeScript compiler for all of these cases.
  2285  
  2286  ## 0.14.37
  2287  
  2288  * Add support for TypeScript's `moduleSuffixes` field from TypeScript 4.7
  2289  
  2290      The upcoming version of TypeScript adds the `moduleSuffixes` field to `tsconfig.json` that introduces more rules to import path resolution. Setting `moduleSuffixes` to `[".ios", ".native", ""]` will try to look at the relative files `./foo.ios.ts`, `./foo.native.ts`, and finally `./foo.ts` for an import path of `./foo`. Note that the empty string `""` in `moduleSuffixes` is necessary for TypeScript to also look-up `./foo.ts`. This was announced in the [TypeScript 4.7 beta blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#resolution-customization-with-modulesuffixes).
  2291  
  2292  * Match the new ASI behavior from TypeScript nightly builds ([#2188](https://github.com/evanw/esbuild/pull/2188))
  2293  
  2294      This release updates esbuild to match some very recent behavior changes in the TypeScript parser regarding automatic semicolon insertion. For more information, see TypeScript issues #48711 and #48654 (I'm not linking to them directly to avoid Dependabot linkback spam on these issues due to esbuild's popularity). The result is that the following TypeScript code is now considered valid TypeScript syntax:
  2295  
  2296      ```ts
  2297      class A<T> {}
  2298      new A<number> /* ASI now happens here */
  2299      if (0) {}
  2300  
  2301      interface B {
  2302        (a: number): typeof a /* ASI now happens here */
  2303        <T>(): void
  2304      }
  2305      ```
  2306  
  2307      This fix was contributed by [@g-plane](https://github.com/g-plane).
  2308  
  2309  ## 0.14.36
  2310  
  2311  * Revert path metadata validation for now ([#2177](https://github.com/evanw/esbuild/issues/2177))
  2312  
  2313      This release reverts the path metadata validation that was introduced in the previous release. This validation has uncovered a potential issue with how esbuild handles `onResolve` callbacks in plugins that will need to be fixed before path metadata validation is re-enabled.
  2314  
  2315  ## 0.14.35
  2316  
  2317  * Add support for parsing `typeof` on #private fields from TypeScript 4.7 ([#2174](https://github.com/evanw/esbuild/pull/2174))
  2318  
  2319      The upcoming version of TypeScript now lets you use `#private` fields in `typeof` type expressions:
  2320  
  2321      https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#typeof-on-private-fields
  2322  
  2323      ```ts
  2324      class Container {
  2325        #data = "hello!";
  2326  
  2327        get data(): typeof this.#data {
  2328          return this.#data;
  2329        }
  2330  
  2331        set data(value: typeof this.#data) {
  2332          this.#data = value;
  2333        }
  2334      }
  2335      ```
  2336  
  2337      With this release, esbuild can now parse these new type expressions as well. This feature was contributed by [@magic-akari](https://github.com/magic-akari).
  2338  
  2339  * Add Opera and IE to internal CSS feature support matrix ([#2170](https://github.com/evanw/esbuild/pull/2170))
  2340  
  2341      Version 0.14.18 of esbuild added Opera and IE as available target environments, and added them to the internal JS feature support matrix. CSS feature support was overlooked, however. This release adds knowledge of Opera and IE to esbuild's internal CSS feature support matrix:
  2342  
  2343      ```css
  2344      /* Original input */
  2345      a {
  2346        color: rgba(0, 0, 0, 0.5);
  2347      }
  2348  
  2349      /* Old output (with --target=opera49 --minify) */
  2350      a{color:rgba(0,0,0,.5)}
  2351  
  2352      /* New output (with --target=opera49 --minify) */
  2353      a{color:#00000080}
  2354      ```
  2355  
  2356      The fix for this issue was contributed by [@sapphi-red](https://github.com/sapphi-red).
  2357  
  2358  * Change TypeScript class field behavior when targeting ES2022
  2359  
  2360      TypeScript 4.3 introduced a breaking change where class field behavior changes from assign semantics to define semantics when the `target` setting in `tsconfig.json` is set to `ESNext`. Specifically, the default value for TypeScript's `useDefineForClassFields` setting when unspecified is `true` if and only if `target` is `ESNext`. TypeScript 4.6 introduced another change where this behavior now happens for both `ESNext` and `ES2022`. Presumably this will be the case for `ES2023` and up as well. With this release, esbuild's behavior has also been changed to match. Now configuring esbuild with `--target=es2022` will also cause TypeScript files to use the new class field behavior.
  2361  
  2362  * Validate that path metadata returned by plugins is consistent
  2363  
  2364      The plugin API assumes that all metadata for the same path returned by a plugin's `onResolve` callback is consistent. Previously this assumption was just assumed without any enforcement. Starting with this release, esbuild will now enforce this by generating a build error if this assumption is violated. The lack of validation has not been an issue (I have never heard of this being a problem), but it still seems like a good idea to enforce it. Here's a simple example of a plugin that generates inconsistent `sideEffects` metadata:
  2365  
  2366      ```js
  2367      let buggyPlugin = {
  2368        name: 'buggy',
  2369        setup(build) {
  2370          let count = 0
  2371          build.onResolve({ filter: /^react$/ }, args => {
  2372            return {
  2373              path: require.resolve(args.path),
  2374              sideEffects: count++ > 0,
  2375            }
  2376          })
  2377        },
  2378      }
  2379      ```
  2380  
  2381      Since esbuild processes everything in parallel, the set of metadata that ends up being used for a given path is essentially random since it's whatever the task scheduler decides to schedule first. Thus if a plugin does not consistently provide the same metadata for a given path, subsequent builds may return different results. This new validation check prevents this problem.
  2382  
  2383      Here's the new error message that's shown when this happens:
  2384  
  2385      ```
  2386      ✘ [ERROR] [plugin buggy] Detected inconsistent metadata for the path "node_modules/react/index.js" when it was imported here:
  2387  
  2388          button.tsx:1:30:
  2389            1 │ import { createElement } from 'react'
  2390              ╵                               ~~~~~~~
  2391  
  2392        The original metadata for that path comes from when it was imported here:
  2393  
  2394          app.tsx:1:23:
  2395            1 │ import * as React from 'react'
  2396              ╵                        ~~~~~~~
  2397  
  2398        The difference in metadata is displayed below:
  2399  
  2400         {
  2401        -  "sideEffects": true,
  2402        +  "sideEffects": false,
  2403         }
  2404  
  2405        This is a bug in the "buggy" plugin. Plugins provide metadata for a given path in an "onResolve"
  2406        callback. All metadata provided for the same path must be consistent to ensure deterministic
  2407        builds. Due to parallelism, one set of provided metadata will be randomly chosen for a given path,
  2408        so providing inconsistent metadata for the same path can cause non-determinism.
  2409      ```
  2410  
  2411  * Suggest enabling a missing condition when `exports` map fails ([#2163](https://github.com/evanw/esbuild/issues/2163))
  2412  
  2413      This release adds another suggestion to the error message that happens when an `exports` map lookup fails if the failure could potentially be fixed by adding a missing condition. Here's what the new error message looks like (which now suggests `--conditions=module` as a possible workaround):
  2414  
  2415      ```
  2416      ✘ [ERROR] Could not resolve "@sentry/electron/main"
  2417  
  2418          index.js:1:24:
  2419            1 │ import * as Sentry from '@sentry/electron/main'
  2420              ╵                         ~~~~~~~~~~~~~~~~~~~~~~~
  2421  
  2422        The path "./main" is not currently exported by package "@sentry/electron":
  2423  
  2424          node_modules/@sentry/electron/package.json:8:13:
  2425            8 │   "exports": {
  2426              ╵              ^
  2427  
  2428        None of the conditions provided ("require", "module") match any of the currently active conditions
  2429        ("browser", "default", "import"):
  2430  
  2431          node_modules/@sentry/electron/package.json:16:14:
  2432            16 │     "./main": {
  2433               ╵               ^
  2434  
  2435        Consider enabling the "module" condition if this package expects it to be enabled. You can use
  2436        "--conditions=module" to do that:
  2437  
  2438          node_modules/@sentry/electron/package.json:18:6:
  2439            18 │       "module": "./esm/main/index.js"
  2440               ╵       ~~~~~~~~
  2441  
  2442        Consider using a "require()" call to import this file, which will work because the "require"
  2443        condition is supported by this package:
  2444  
  2445          index.js:1:24:
  2446            1 │ import * as Sentry from '@sentry/electron/main'
  2447              ╵                         ~~~~~~~~~~~~~~~~~~~~~~~
  2448  
  2449        You can mark the path "@sentry/electron/main" as external to exclude it from the bundle, which
  2450        will remove this error.
  2451      ```
  2452  
  2453      This particular package had an issue where it was using the Webpack-specific `module` condition without providing a `default` condition. It looks like the intent in this case was to use the standard `import` condition instead. This specific change wasn't suggested here because this error message is for package consumers, not package authors.
  2454  
  2455  ## 0.14.34
  2456  
  2457  Something went wrong with the publishing script for the previous release. Publishing again.
  2458  
  2459  ## 0.14.33
  2460  
  2461  * Fix a regression regarding `super` ([#2158](https://github.com/evanw/esbuild/issues/2158))
  2462  
  2463      This fixes a regression from the previous release regarding classes with a super class, a private member, and a static field in the scenario where the static field needs to be lowered but where private members are supported by the configured target environment. In this scenario, esbuild could incorrectly inject the instance field initializers that use `this` into the constructor before the call to `super()`, which is invalid. This problem has now been fixed (notice that `this` is now used after `super()` instead of before):
  2464  
  2465      ```js
  2466      // Original code
  2467      class Foo extends Object {
  2468        static FOO;
  2469        constructor() {
  2470          super();
  2471        }
  2472        #foo;
  2473      }
  2474  
  2475      // Old output (with --bundle)
  2476      var _foo;
  2477      var Foo = class extends Object {
  2478        constructor() {
  2479          __privateAdd(this, _foo, void 0);
  2480          super();
  2481        }
  2482      };
  2483      _foo = new WeakMap();
  2484      __publicField(Foo, "FOO");
  2485  
  2486      // New output (with --bundle)
  2487      var _foo;
  2488      var Foo = class extends Object {
  2489        constructor() {
  2490          super();
  2491          __privateAdd(this, _foo, void 0);
  2492        }
  2493      };
  2494      _foo = new WeakMap();
  2495      __publicField(Foo, "FOO");
  2496      ```
  2497  
  2498      During parsing, esbuild scans the class and makes certain decisions about the class such as whether to lower all static fields, whether to lower each private member, or whether calls to `super()` need to be tracked and adjusted. Previously esbuild made two passes through the class members to compute this information. However, with the new `super()` call lowering logic added in the previous release, we now need three passes to capture the whole dependency chain for this case: 1) lowering static fields requires 2) lowering private members which requires 3) adjusting `super()` calls.
  2499  
  2500      The reason lowering static fields requires lowering private members is because lowering static fields moves their initializers outside of the class body, where they can't access private members anymore. Consider this code:
  2501  
  2502      ```js
  2503      class Foo {
  2504        get #foo() {}
  2505        static bar = new Foo().#foo
  2506      }
  2507      ```
  2508  
  2509      We can't just lower static fields without also lowering private members, since that causes a syntax error:
  2510  
  2511      ```js
  2512      class Foo {
  2513        get #foo() {}
  2514      }
  2515      Foo.bar = new Foo().#foo;
  2516      ```
  2517  
  2518      And the reason lowering private members requires adjusting `super()` calls is because the injected private member initializers use `this`, which is only accessible after `super()` calls in the constructor.
  2519  
  2520  * Fix an issue with `--keep-names` not keeping some names ([#2149](https://github.com/evanw/esbuild/issues/2149))
  2521  
  2522      This release fixes a regression with `--keep-names` from version 0.14.26. PR [#2062](https://github.com/evanw/esbuild/pull/2062) attempted to remove superfluous calls to the `__name` helper function by omitting calls of the form `__name(foo, "foo")` where the name of the symbol in the first argument is equal to the string in the second argument. This was assuming that the initializer for the symbol would automatically be assigned the expected `.name` property by the JavaScript VM, which turned out to be an incorrect assumption. To fix the regression, this PR has been reverted.
  2523  
  2524      The assumption is true in many cases but isn't true when the initializer is moved into another automatically-generated variable, which can sometimes be necessary during the various syntax transformations that esbuild does. For example, consider the following code:
  2525  
  2526      ```js
  2527      class Foo {
  2528        static get #foo() { return Foo.name }
  2529        static get foo() { return this.#foo }
  2530      }
  2531      let Bar = Foo
  2532      Foo = { name: 'Bar' }
  2533      console.log(Foo.name, Bar.name)
  2534      ```
  2535  
  2536      This code should print `Bar Foo`. With `--keep-names --target=es6` that code is lowered by esbuild into the following code (omitting the helper function definitions for brevity):
  2537  
  2538      ```js
  2539      var _foo, foo_get;
  2540      const _Foo = class {
  2541        static get foo() {
  2542          return __privateGet(this, _foo, foo_get);
  2543        }
  2544      };
  2545      let Foo = _Foo;
  2546      __name(Foo, "Foo");
  2547      _foo = new WeakSet();
  2548      foo_get = /* @__PURE__ */ __name(function() {
  2549        return _Foo.name;
  2550      }, "#foo");
  2551      __privateAdd(Foo, _foo);
  2552      let Bar = Foo;
  2553      Foo = { name: "Bar" };
  2554      console.log(Foo.name, Bar.name);
  2555      ```
  2556  
  2557      The injection of the automatically-generated `_Foo` variable is necessary to preserve the semantics of the captured `Foo` binding for methods defined within the class body, even when the definition needs to be moved outside of the class body during code transformation. Due to a JavaScript quirk, this binding is immutable and does not change even if `Foo` is later reassigned. The PR that was reverted was incorrectly removing the call to `__name(Foo, "Foo")`, which turned out to be necessary after all in this case.
  2558  
  2559  * Print some large integers using hexadecimal when minifying ([#2162](https://github.com/evanw/esbuild/issues/2162))
  2560  
  2561      When `--minify` is active, esbuild will now use one fewer byte to represent certain large integers:
  2562  
  2563      ```js
  2564      // Original code
  2565      x = 123456787654321;
  2566  
  2567      // Old output (with --minify)
  2568      x=123456787654321;
  2569  
  2570      // New output (with --minify)
  2571      x=0x704885f926b1;
  2572      ```
  2573  
  2574      This works because a hexadecimal representation can be shorter than a decimal representation starting at around 10<sup>12</sup> and above.
  2575  
  2576      _This optimization made me realize that there's probably an opportunity to optimize printed numbers for smaller gzipped size instead of or in addition to just optimizing for minimal uncompressed byte count. The gzip algorithm does better with repetitive sequences, so for example `0xFFFFFFFF` is probably a better representation than `4294967295` even though the byte counts are the same. As far as I know, no JavaScript minifier does this optimization yet. I don't know enough about how gzip works to know if this is a good idea or what the right metric for this might be._
  2577  
  2578  * Add Linux ARM64 support for Deno ([#2156](https://github.com/evanw/esbuild/issues/2156))
  2579  
  2580      This release adds Linux ARM64 support to esbuild's [Deno](https://deno.land/) API implementation, which allows esbuild to be used with Deno on a Raspberry Pi.
  2581  
  2582  ## 0.14.32
  2583  
  2584  * Fix `super` usage in lowered private methods ([#2039](https://github.com/evanw/esbuild/issues/2039))
  2585  
  2586      Previously esbuild failed to transform `super` property accesses inside private methods in the case when private methods have to be lowered because the target environment doesn't support them. The generated code still contained the `super` keyword even though the method was moved outside of the class body, which is a syntax error in JavaScript. This release fixes this transformation issue and now produces valid code:
  2587  
  2588      ```js
  2589      // Original code
  2590      class Derived extends Base {
  2591        #foo() { super.foo() }
  2592        bar() { this.#foo() }
  2593      }
  2594  
  2595      // Old output (with --target=es6)
  2596      var _foo, foo_fn;
  2597      class Derived extends Base {
  2598        constructor() {
  2599          super(...arguments);
  2600          __privateAdd(this, _foo);
  2601        }
  2602        bar() {
  2603          __privateMethod(this, _foo, foo_fn).call(this);
  2604        }
  2605      }
  2606      _foo = new WeakSet();
  2607      foo_fn = function() {
  2608        super.foo();
  2609      };
  2610  
  2611      // New output (with --target=es6)
  2612      var _foo, foo_fn;
  2613      const _Derived = class extends Base {
  2614        constructor() {
  2615          super(...arguments);
  2616          __privateAdd(this, _foo);
  2617        }
  2618        bar() {
  2619          __privateMethod(this, _foo, foo_fn).call(this);
  2620        }
  2621      };
  2622      let Derived = _Derived;
  2623      _foo = new WeakSet();
  2624      foo_fn = function() {
  2625        __superGet(_Derived.prototype, this, "foo").call(this);
  2626      };
  2627      ```
  2628  
  2629      Because of this change, lowered `super` property accesses on instances were rewritten so that they can exist outside of the class body. This rewrite affects code generation for all `super` property accesses on instances including those inside lowered `async` functions. The new approach is different but should be equivalent to the old approach:
  2630  
  2631      ```js
  2632      // Original code
  2633      class Foo {
  2634        foo = async () => super.foo()
  2635      }
  2636  
  2637      // Old output (with --target=es6)
  2638      class Foo {
  2639        constructor() {
  2640          __publicField(this, "foo", () => {
  2641            var __superGet = (key) => super[key];
  2642            return __async(this, null, function* () {
  2643              return __superGet("foo").call(this);
  2644            });
  2645          });
  2646        }
  2647      }
  2648  
  2649      // New output (with --target=es6)
  2650      class Foo {
  2651        constructor() {
  2652          __publicField(this, "foo", () => __async(this, null, function* () {
  2653            return __superGet(Foo.prototype, this, "foo").call(this);
  2654          }));
  2655        }
  2656      }
  2657      ```
  2658  
  2659  * Fix some tree-shaking bugs regarding property side effects
  2660  
  2661      This release fixes some cases where side effects in computed properties were not being handled correctly. Specifically primitives and private names as properties should not be considered to have side effects, and object literals as properties should be considered to have side effects:
  2662  
  2663      ```js
  2664      // Original code
  2665      let shouldRemove = { [1]: 2 }
  2666      let shouldRemove2 = class { #foo }
  2667      let shouldKeep = class { [{ toString() { sideEffect() } }] }
  2668  
  2669      // Old output (with --tree-shaking=true)
  2670      let shouldRemove = { [1]: 2 };
  2671      let shouldRemove2 = class {
  2672        #foo;
  2673      };
  2674  
  2675      // New output (with --tree-shaking=true)
  2676      let shouldKeep = class {
  2677        [{ toString() {
  2678          sideEffect();
  2679        } }];
  2680      };
  2681      ```
  2682  
  2683  * Add the `wasmModule` option to the `initialize` JS API ([#1093](https://github.com/evanw/esbuild/issues/1093))
  2684  
  2685      The `initialize` JS API must be called when using esbuild in the browser to provide the WebAssembly module for esbuild to use. Previously the only way to do that was using the `wasmURL` API option like this:
  2686  
  2687      ```js
  2688      await esbuild.initialize({
  2689        wasmURL: '/node_modules/esbuild-wasm/esbuild.wasm',
  2690      })
  2691      console.log(await esbuild.transform('1+2'))
  2692      ```
  2693  
  2694      With this release, you can now also initialize esbuild using a `WebAssembly.Module` instance using the `wasmModule` API option instead. The example above is equivalent to the following code:
  2695  
  2696      ```js
  2697      await esbuild.initialize({
  2698        wasmModule: await WebAssembly.compileStreaming(fetch('/node_modules/esbuild-wasm/esbuild.wasm'))
  2699      })
  2700      console.log(await esbuild.transform('1+2'))
  2701      ```
  2702  
  2703      This could be useful for environments where you want more control over how the WebAssembly download happens or where downloading the WebAssembly module is not possible.
  2704  
  2705  ## 0.14.31
  2706  
  2707  * Add support for parsing "optional variance annotations" from TypeScript 4.7 ([#2102](https://github.com/evanw/esbuild/pull/2102))
  2708  
  2709      The upcoming version of TypeScript now lets you specify `in` and/or `out` on certain type parameters (specifically only on a type alias, an interface declaration, or a class declaration). These modifiers control type parameter covariance and contravariance:
  2710  
  2711      ```ts
  2712      type Provider<out T> = () => T;
  2713      type Consumer<in T> = (x: T) => void;
  2714      type Mapper<in T, out U> = (x: T) => U;
  2715      type Processor<in out T> = (x: T) => T;
  2716      ```
  2717  
  2718      With this release, esbuild can now parse these new type parameter modifiers. This feature was contributed by [@magic-akari](https://github.com/magic-akari).
  2719  
  2720  * Improve support for `super()` constructor calls in nested locations ([#2134](https://github.com/evanw/esbuild/issues/2134))
  2721  
  2722      In JavaScript, derived classes must call `super()` somewhere in the `constructor` method before being able to access `this`. Class public instance fields, class private instance fields, and TypeScript constructor parameter properties can all potentially cause code which uses `this` to be inserted into the constructor body, which must be inserted after the `super()` call. To make these insertions straightforward to implement, the TypeScript compiler doesn't allow calling `super()` somewhere other than in a root-level statement in the constructor body in these cases.
  2723  
  2724      Previously esbuild's class transformations only worked correctly when `super()` was called in a root-level statement in the constructor body, just like the TypeScript compiler. But with this release, esbuild should now generate correct code as long as the call to `super()` appears anywhere in the constructor body:
  2725  
  2726      ```ts
  2727      // Original code
  2728      class Foo extends Bar {
  2729        constructor(public skip = false) {
  2730          if (skip) {
  2731            super(null)
  2732            return
  2733          }
  2734          super({ keys: [] })
  2735        }
  2736      }
  2737  
  2738      // Old output (incorrect)
  2739      class Foo extends Bar {
  2740        constructor(skip = false) {
  2741          if (skip) {
  2742            super(null);
  2743            return;
  2744          }
  2745          super({ keys: [] });
  2746          this.skip = skip;
  2747        }
  2748      }
  2749  
  2750      // New output (correct)
  2751      class Foo extends Bar {
  2752        constructor(skip = false) {
  2753          var __super = (...args) => {
  2754            super(...args);
  2755            this.skip = skip;
  2756          };
  2757          if (skip) {
  2758            __super(null);
  2759            return;
  2760          }
  2761          __super({ keys: [] });
  2762        }
  2763      }
  2764      ```
  2765  
  2766  * Add support for the new `@container` CSS rule ([#2127](https://github.com/evanw/esbuild/pull/2127))
  2767  
  2768      This release adds support for [`@container`](https://drafts.csswg.org/css-contain-3/#container-rule) in CSS files. This means esbuild will now pretty-print and minify these rules better since it now better understands the internal structure of these rules:
  2769  
  2770      ```css
  2771      /* Original code */
  2772      @container (width <= 150px) {
  2773        #inner {
  2774          color: yellow;
  2775        }
  2776      }
  2777  
  2778      /* Old output (with --minify) */
  2779      @container (width <= 150px){#inner {color: yellow;}}
  2780  
  2781      /* New output (with --minify) */
  2782      @container (width <= 150px){#inner{color:#ff0}}
  2783      ```
  2784  
  2785      This was contributed by [@yisibl](https://github.com/yisibl).
  2786  
  2787  * Avoid CSS cascade-dependent keywords in the `font-family` property ([#2135](https://github.com/evanw/esbuild/pull/2135))
  2788  
  2789      In CSS, [`initial`](https://developer.mozilla.org/en-US/docs/Web/CSS/initial), [`inherit`](https://developer.mozilla.org/en-US/docs/Web/CSS/inherit), and [`unset`](https://developer.mozilla.org/en-US/docs/Web/CSS/unset) are [CSS-wide keywords](https://drafts.csswg.org/css-values-4/#css-wide-keywords) which means they have special behavior when they are specified as a property value. For example, while `font-family: 'Arial'` (as a string) and `font-family: Arial` (as an identifier) are the same, `font-family: 'inherit'` (as a string) uses the font family named `inherit` but `font-family: inherit` (as an identifier) inherits the font family from the parent element. This means esbuild must not unquote these CSS-wide keywords (and `default`, which is also reserved) during minification to avoid changing the meaning of the minified CSS.
  2790  
  2791      The current draft of the new CSS Cascading and Inheritance Level 5 specification adds another concept called [cascade-dependent keywords](https://drafts.csswg.org/css-cascade-5/#defaulting-keywords) of which there are two: [`revert`](https://developer.mozilla.org/en-US/docs/Web/CSS/revert) and [`revert-layer`](https://developer.mozilla.org/en-US/docs/Web/CSS/revert-layer). This release of esbuild guards against unquoting these additional keywords as well to avoid accidentally breaking pages that use a font with the same name:
  2792  
  2793      ```css
  2794      /* Original code */
  2795      a { font-family: 'revert'; }
  2796      b { font-family: 'revert-layer', 'Segoe UI', serif; }
  2797  
  2798      /* Old output (with --minify) */
  2799      a{font-family:revert}b{font-family:revert-layer,Segoe UI,serif}
  2800  
  2801      /* New output (with --minify) */
  2802      a{font-family:"revert"}b{font-family:"revert-layer",Segoe UI,serif}
  2803      ```
  2804  
  2805      This fix was contributed by [@yisibl](https://github.com/yisibl).
  2806  
  2807  ## 0.14.30
  2808  
  2809  * Change the context of TypeScript parameter decorators ([#2147](https://github.com/evanw/esbuild/issues/2147))
  2810  
  2811      While TypeScript parameter decorators are expressions, they are not evaluated where they exist in the code. They are moved to after the class declaration and evaluated there instead. Specifically this TypeScript code:
  2812  
  2813      ```ts
  2814      class Class {
  2815        method(@decorator() arg) {}
  2816      }
  2817      ```
  2818  
  2819      becomes this JavaScript code:
  2820  
  2821      ```js
  2822      class Class {
  2823        method(arg) {}
  2824      }
  2825      __decorate([
  2826        __param(0, decorator())
  2827      ], Class.prototype, "method", null);
  2828      ```
  2829  
  2830      This has several consequences:
  2831  
  2832      * Whether `await` is allowed inside a decorator expression or not depends on whether the class declaration itself is in an `async` context or not. With this release, you can now use `await` inside a decorator expression when the class declaration is either inside an `async` function or is at the top-level of an ES module and top-level await is supported. Note that the TypeScript compiler currently has a bug regarding this edge case: https://github.com/microsoft/TypeScript/issues/48509.
  2833  
  2834          ```ts
  2835          // Using "await" inside a decorator expression is now allowed
  2836          async function fn(foo: Promise<any>) {
  2837            class Class {
  2838              method(@decorator(await foo) arg) {}
  2839            }
  2840            return Class
  2841          }
  2842          ```
  2843  
  2844          Also while TypeScript currently allows `await` to be used like this in `async` functions, it doesn't currently allow `yield` to be used like this in generator functions. It's not yet clear whether this behavior with `yield` is a bug or by design, so I haven't made any changes to esbuild's handling of `yield` inside decorator expressions in this release.
  2845  
  2846      * Since the scope of a decorator expression is the scope enclosing the class declaration, they cannot access private identifiers. Previously this was incorrectly allowed but with this release, esbuild no longer allows this. Note that the TypeScript compiler currently has a bug regarding this edge case: https://github.com/microsoft/TypeScript/issues/48515.
  2847  
  2848          ```ts
  2849          // Using private names inside a decorator expression is no longer allowed
  2850          class Class {
  2851            static #priv = 123
  2852            method(@decorator(Class.#priv) arg) {}
  2853          }
  2854          ```
  2855  
  2856      * Since the scope of a decorator expression is the scope enclosing the class declaration, identifiers inside parameter decorator expressions should never be resolved to a parameter of the enclosing method. Previously this could happen, which was a bug with esbuild. This bug no longer happens in this release.
  2857  
  2858          ```ts
  2859          // Name collisions now resolve to the outer name instead of the inner name
  2860          let arg = 1
  2861          class Class {
  2862            method(@decorator(arg) arg = 2) {}
  2863          }
  2864          ```
  2865  
  2866          Specifically previous versions of esbuild generated the following incorrect JavaScript (notice the use of `arg2`):
  2867  
  2868          ```js
  2869          let arg = 1;
  2870          class Class {
  2871            method(arg2 = 2) {
  2872            }
  2873          }
  2874          __decorateClass([
  2875            __decorateParam(0, decorator(arg2))
  2876          ], Class.prototype, "method", 1);
  2877          ```
  2878  
  2879          This release now generates the following correct JavaScript (notice the use of `arg`):
  2880  
  2881          ```js
  2882          let arg = 1;
  2883          class Class {
  2884            method(arg2 = 2) {
  2885            }
  2886          }
  2887          __decorateClass([
  2888            __decorateParam(0, decorator(arg))
  2889          ], Class.prototype, "method", 1);
  2890          ```
  2891  
  2892  * Fix some obscure edge cases with `super` property access
  2893  
  2894      This release fixes the following obscure problems with `super` when targeting an older JavaScript environment such as `--target=es6`:
  2895  
  2896      1. The compiler could previously crash when a lowered `async` arrow function contained a class with a field initializer that used a `super` property access:
  2897  
  2898          ```js
  2899          let foo = async () => class extends Object {
  2900            bar = super.toString
  2901          }
  2902          ```
  2903  
  2904      2. The compiler could previously generate incorrect code when a lowered `async` method of a derived class contained a nested class with a computed class member involving a `super` property access on the derived class:
  2905  
  2906          ```js
  2907          class Base {
  2908            foo() { return 'bar' }
  2909          }
  2910          class Derived extends Base {
  2911            async foo() {
  2912              return new class { [super.foo()] = 'success' }
  2913            }
  2914          }
  2915          new Derived().foo().then(obj => console.log(obj.bar))
  2916          ```
  2917  
  2918      3. The compiler could previously generate incorrect code when a default-exported class contained a `super` property access inside a lowered static private class field:
  2919  
  2920          ```js
  2921          class Foo {
  2922            static foo = 123
  2923          }
  2924          export default class extends Foo {
  2925            static #foo = super.foo
  2926            static bar = this.#foo
  2927          }
  2928          ```
  2929  
  2930  ## 0.14.29
  2931  
  2932  * Fix a minification bug with a double-nested `if` inside a label followed by `else` ([#2139](https://github.com/evanw/esbuild/issues/2139))
  2933  
  2934      This fixes a minification bug that affects the edge case where `if` is followed by `else` and the `if` contains a label that contains a nested `if`. Normally esbuild's AST printer automatically wraps the body of a single-statement `if` in braces to avoid the "dangling else" `if`/`else` ambiguity common to C-like languages (where the `else` accidentally becomes associated with the inner `if` instead of the outer `if`). However, I was missing automatic wrapping of label statements, which did not have test coverage because they are a rarely-used feature. This release fixes the bug:
  2935  
  2936      ```js
  2937      // Original code
  2938      if (a)
  2939        b: {
  2940          if (c) break b
  2941        }
  2942      else if (d)
  2943        e()
  2944  
  2945      // Old output (with --minify)
  2946      if(a)e:if(c)break e;else d&&e();
  2947  
  2948      // New output (with --minify)
  2949      if(a){e:if(c)break e}else d&&e();
  2950      ```
  2951  
  2952  * Fix edge case regarding `baseUrl` and `paths` in `tsconfig.json` ([#2119](https://github.com/evanw/esbuild/issues/2119))
  2953  
  2954      In `tsconfig.json`, TypeScript forbids non-relative values inside `paths` if `baseUrl` is not present, and esbuild does too. However, TypeScript checked this after the entire `tsconfig.json` hierarchy was parsed while esbuild incorrectly checked this immediately when parsing the file containing the `paths` map. This caused incorrect warnings to be generated for `tsconfig.json` files that specify a `baseUrl` value and that inherit a `paths` value from an `extends` clause. Now esbuild will only check for non-relative `paths` values after the entire hierarchy has been parsed to avoid generating incorrect warnings.
  2955  
  2956  * Better handle errors where the esbuild binary executable is corrupted or missing ([#2129](https://github.com/evanw/esbuild/issues/2129))
  2957  
  2958      If the esbuild binary executable is corrupted or missing, previously there was one situation where esbuild's JavaScript API could hang instead of generating an error. This release changes esbuild's library code to generate an error instead in this case.
  2959  
  2960  ## 0.14.28
  2961  
  2962  * Add support for some new CSS rules ([#2115](https://github.com/evanw/esbuild/issues/2115), [#2116](https://github.com/evanw/esbuild/issues/2116), [#2117](https://github.com/evanw/esbuild/issues/2117))
  2963  
  2964      This release adds support for [`@font-palette-values`](https://drafts.csswg.org/css-fonts-4/#font-palette-values), [`@counter-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style), and [`@font-feature-values`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-feature-values). This means esbuild will now pretty-print and minify these rules better since it now better understands the internal structure of these rules:
  2965  
  2966      ```css
  2967      /* Original code */
  2968      @font-palette-values --Foo { base-palette: 1; }
  2969      @counter-style bar { symbols: b a r; }
  2970      @font-feature-values Bop { @styleset { test: 1; } }
  2971  
  2972      /* Old output (with --minify) */
  2973      @font-palette-values --Foo{base-palette: 1;}@counter-style bar{symbols: b a r;}@font-feature-values Bop{@styleset {test: 1;}}
  2974  
  2975      /* New output (with --minify) */
  2976      @font-palette-values --Foo{base-palette:1}@counter-style bar{symbols:b a r}@font-feature-values Bop{@styleset{test:1}}
  2977      ```
  2978  
  2979  * Upgrade to Go 1.18.0 ([#2105](https://github.com/evanw/esbuild/issues/2105))
  2980  
  2981      Binary executables for this version are now published with Go version 1.18.0. The [Go release notes](https://go.dev/doc/go1.18) say that the linker generates smaller binaries and that on 64-bit ARM chips, compiled binaries run around 10% faster. On an M1 MacBook Pro, esbuild's benchmark runs approximately 8% faster than before and the binary executable is approximately 4% smaller than before.
  2982  
  2983      This also fixes a regression from version 0.14.26 of esbuild where the browser builds of the `esbuild-wasm` package could fail to be bundled due to the use of built-in node libraries. The primary WebAssembly shim for Go 1.18.0 no longer uses built-in node libraries.
  2984  
  2985  ## 0.14.27
  2986  
  2987  * Avoid generating an enumerable `default` import for CommonJS files in Babel mode ([#2097](https://github.com/evanw/esbuild/issues/2097))
  2988  
  2989      Importing a CommonJS module into an ES module can be done in two different ways. In node mode the `default` import is always set to `module.exports`, while in Babel mode the `default` import passes through to `module.exports.default` instead. Node mode is triggered when the importing file ends in `.mjs`, has `type: "module"` in its `package.json` file, or the imported module does not have a `__esModule` marker.
  2990  
  2991      Previously esbuild always created the forwarding `default` import in Babel mode, even if `module.exports` had no property called `default`. This was problematic because the getter named `default` still showed up as a property on the imported namespace object, and could potentially interfere with code that iterated over the properties of the imported namespace object. With this release the getter named `default` will now only be added in Babel mode if the `default` property exists at the time of the import.
  2992  
  2993  * Fix a circular import edge case regarding ESM-to-CommonJS conversion ([#1894](https://github.com/evanw/esbuild/issues/1894), [#2059](https://github.com/evanw/esbuild/pull/2059))
  2994  
  2995      This fixes a regression that was introduced in version 0.14.5 of esbuild. Ever since that version, esbuild now creates two separate export objects when you convert an ES module file into a CommonJS module: one for ES modules and one for CommonJS modules. The one for CommonJS modules is written to `module.exports` and exported from the file, and the one for ES modules is internal and can be accessed by bundling code that imports the entry point (for example, the entry point might import itself to be able to inspect its own exports).
  2996  
  2997      The reason for these two separate export objects is that CommonJS modules are supposed to see a special export called `__esModule` which indicates that the module used to be an ES module, while ES modules are not supposed to see any automatically-added export named `__esModule`. This matters for real-world code both because people sometimes iterate over the properties of ES module export namespace objects and because some people write ES module code containing their own exports named `__esModule` that they expect other ES module code to be able to read.
  2998  
  2999      However, this change to split exports into two separate objects broke ES module re-exports in the edge case where the imported module is involved in an import cycle. This happened because the CommonJS `module.exports` object was no longer mutated as exports were added. Instead it was being initialized at the end of the generated file after the import statements to other modules (which are converted into `require()` calls). This release changes `module.exports` initialization to happen earlier in the file and then double-writes further exports to both the ES module and CommonJS module export objects.
  3000  
  3001      This fix was contributed by [@indutny](https://github.com/indutny).
  3002  
  3003  ## 0.14.26
  3004  
  3005  * Fix a tree shaking regression regarding `var` declarations ([#2080](https://github.com/evanw/esbuild/issues/2080), [#2085](https://github.com/evanw/esbuild/pull/2085), [#2098](https://github.com/evanw/esbuild/issues/2098), [#2099](https://github.com/evanw/esbuild/issues/2099))
  3006  
  3007      Version 0.14.8 of esbuild enabled removal of duplicate function declarations when minification is enabled (see [#610](https://github.com/evanw/esbuild/issues/610)):
  3008  
  3009      ```js
  3010      // Original code
  3011      function x() { return 1 }
  3012      console.log(x())
  3013      function x() { return 2 }
  3014  
  3015      // Output (with --minify-syntax)
  3016      console.log(x());
  3017      function x() {
  3018        return 2;
  3019      }
  3020      ```
  3021  
  3022      This transformation is safe because function declarations are "hoisted" in JavaScript, which means they are all done first before any other code is evaluted. This means the last function declaration will overwrite all previous function declarations with the same name.
  3023  
  3024      However, this introduced an unintentional regression for `var` declarations in which all but the last declaration was dropped if tree-shaking was enabled. This only happens for top-level `var` declarations that re-declare the same variable multiple times. This regression has now been fixed:
  3025  
  3026      ```js
  3027      // Original code
  3028      var x = 1
  3029      console.log(x)
  3030      var x = 2
  3031  
  3032      // Old output (with --tree-shaking=true)
  3033      console.log(x);
  3034      var x = 2;
  3035  
  3036      // New output (with --tree-shaking=true)
  3037      var x = 1;
  3038      console.log(x);
  3039      var x = 2;
  3040      ```
  3041  
  3042      This case now has test coverage.
  3043  
  3044  * Add support for parsing "instantiation expressions" from TypeScript 4.7 ([#2038](https://github.com/evanw/esbuild/pull/2038))
  3045  
  3046      The upcoming version of TypeScript now lets you specify `<...>` type parameters on a JavaScript identifier without using a call expression:
  3047  
  3048      ```ts
  3049      const ErrorMap = Map<string, Error>;  // new () => Map<string, Error>
  3050      const errorMap = new ErrorMap();  // Map<string, Error>
  3051      ```
  3052  
  3053      With this release, esbuild can now parse these new type annotations. This feature was contributed by [@g-plane](https://github.com/g-plane).
  3054  
  3055  * Avoid `new Function` in esbuild's library code ([#2081](https://github.com/evanw/esbuild/issues/2081))
  3056  
  3057      Some JavaScript environments such as Cloudflare Workers or Deno Deploy don't allow `new Function` because they disallow dynamic JavaScript evaluation. Previously esbuild's WebAssembly-based library used this to construct the WebAssembly worker function. With this release, the code is now inlined without using `new Function` so it will be able to run even when this restriction is in place.
  3058  
  3059  * Drop superfluous `__name()` calls ([#2062](https://github.com/evanw/esbuild/pull/2062))
  3060  
  3061      When the `--keep-names` option is specified, esbuild inserts calls to a `__name` helper function to ensure that the `.name` property on function and class objects remains consistent even if the function or class name is renamed to avoid a name collision or because name minification is enabled. With this release, esbuild will now try to omit these calls to the `__name` helper function when the name of the function or class object was not renamed during the linking process after all:
  3062  
  3063      ```js
  3064      // Original code
  3065      import { foo as foo1 } from 'data:text/javascript,export function foo() { return "foo1" }'
  3066      import { foo as foo2 } from 'data:text/javascript,export function foo() { return "foo2" }'
  3067      console.log(foo1.name, foo2.name)
  3068  
  3069      // Old output (with --bundle --keep-names)
  3070      (() => {
  3071        var __defProp = Object.defineProperty;
  3072        var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  3073        function foo() {
  3074          return "foo1";
  3075        }
  3076        __name(foo, "foo");
  3077        function foo2() {
  3078          return "foo2";
  3079        }
  3080        __name(foo2, "foo");
  3081        console.log(foo.name, foo2.name);
  3082      })();
  3083  
  3084      // New output (with --bundle --keep-names)
  3085      (() => {
  3086        var __defProp = Object.defineProperty;
  3087        var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  3088        function foo() {
  3089          return "foo1";
  3090        }
  3091        function foo2() {
  3092          return "foo2";
  3093        }
  3094        __name(foo2, "foo");
  3095        console.log(foo.name, foo2.name);
  3096      })();
  3097      ```
  3098  
  3099      Notice how one of the calls to `__name` is now no longer printed. This change was contributed by [@indutny](https://github.com/indutny).
  3100  
  3101  ## 0.14.25
  3102  
  3103  * Reduce minification of CSS transforms to avoid Safari bugs ([#2057](https://github.com/evanw/esbuild/issues/2057))
  3104  
  3105      In Safari, applying a 3D CSS transform to an element can cause it to render in a different order than applying a 2D CSS transform even if the transformation matrix is identical. I believe this is a bug in Safari because the [CSS `transform` specification](https://drafts.csswg.org/css-transforms-1/#transform-rendering) doesn't seem to distinguish between 2D and 3D transforms as far as rendering order:
  3106  
  3107      > For elements whose layout is governed by the CSS box model, any value other than `none` for the `transform` property results in the creation of a stacking context.
  3108  
  3109      This bug means that minifying a 3D transform into a 2D transform must be avoided even though it's a valid transformation because it can cause rendering differences in Safari. Previously esbuild sometimes minified 3D CSS transforms into 2D CSS transforms but with this release, esbuild will no longer do that:
  3110  
  3111      ```css
  3112      /* Original code */
  3113      div { transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }
  3114  
  3115      /* Old output (with --minify) */
  3116      div{transform:scale(2)}
  3117  
  3118      /* New output (with --minify) */
  3119      div{transform:scale3d(2,2,1)}
  3120      ```
  3121  
  3122  * Minification now takes advantage of the `?.` operator
  3123  
  3124      This adds new code minification rules that shorten code with the `?.` optional chaining operator when the result is equivalent:
  3125  
  3126      ```ts
  3127      // Original code
  3128      let foo = (x) => {
  3129        if (x !== null && x !== undefined) x.y()
  3130        return x === null || x === undefined ? undefined : x.z
  3131      }
  3132  
  3133      // Old output (with --minify)
  3134      let foo=n=>(n!=null&&n.y(),n==null?void 0:n.z);
  3135  
  3136      // New output (with --minify)
  3137      let foo=n=>(n?.y(),n?.z);
  3138      ```
  3139  
  3140      This only takes effect when minification is enabled and when the configured target environment is known to support the optional chaining operator. As always, make sure to set `--target=` to the appropriate language target if you are running the minified code in an environment that doesn't support the latest JavaScript features.
  3141  
  3142  * Add source mapping information for some non-executable tokens ([#1448](https://github.com/evanw/esbuild/issues/1448))
  3143  
  3144      Code coverage tools can generate reports that tell you if any code exists that has not been run (or "covered") during your tests. You can use this information to add additional tests for code that isn't currently covered.
  3145  
  3146      Some popular JavaScript code coverage tools have bugs where they incorrectly consider lines without any executable code as uncovered, even though there's no test you could possibly write that would cause those lines to be executed. For example, they apparently complain about the lines that only contain the trailing `}` token of an object literal.
  3147  
  3148      With this release, esbuild now generates source mappings for some of these trailing non-executable tokens. This may not successfully work around bugs in code coverage tools because there are many non-executable tokens in JavaScript and esbuild doesn't map them all (the drawback of mapping these extra tokens is that esbuild will use more memory, build more slowly, and output a bigger source map). The true solution is to fix the bugs in the code coverage tools in the first place.
  3149  
  3150  * Fall back to WebAssembly on Android x64 ([#2068](https://github.com/evanw/esbuild/issues/2068))
  3151  
  3152      Go's compiler supports trivial cross-compiling to almost all platforms without installing any additional software other than the Go compiler itself. This has made it very easy for esbuild to publish native binary executables for many platforms. However, it strangely doesn't support cross-compiling to Android x64 without installing the Android build tools. So instead of publishing a native esbuild binary executable to npm, this release publishes a WebAssembly fallback build. This is essentially the same as the `esbuild-wasm` package but it's installed automatically when you install the `esbuild` package on Android x64. So packages that depend on the `esbuild` package should now work on Android x64. If you want to use a native binary executable of esbuild on Android x64, you may be able to build it yourself from source after installing the Android build tools.
  3153  
  3154  * Update to Go 1.17.8
  3155  
  3156      The version of the Go compiler used to compile esbuild has been upgraded from Go 1.17.7 to Go 1.17.8, which fixes the RISC-V 64-bit build. Compiler optimizations for the RISC-V 64-bit build have now been re-enabled.
  3157  
  3158  ## 0.14.24
  3159  
  3160  * Allow `es2022` as a target environment ([#2012](https://github.com/evanw/esbuild/issues/2012))
  3161  
  3162      TypeScript recently [added support for `es2022`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-6/#target-es2022) as a compilation target so esbuild now supports this too. Support for this is preliminary as there is no published ES2022 specification yet (i.e. https://tc39.es/ecma262/2021/ exists but https://tc39.es/ecma262/2022/ is a 404 error). The meaning of esbuild's `es2022` target may change in the future when the specification is finalized. Right now I have made the `es2022` target enable support for the syntax-related [finished proposals](https://github.com/tc39/proposals/blob/main/finished-proposals.md) that are marked as `2022`:
  3163  
  3164      * Class fields
  3165      * Class private members
  3166      * Class static blocks
  3167      * Ergonomic class private member checks
  3168      * Top-level await
  3169  
  3170      I have also included the "arbitrary module namespace names" feature since I'm guessing it will end up in the ES2022 specification (this syntax feature was added to the specification without a proposal). TypeScript has [not added support for this yet](https://github.com/microsoft/TypeScript/issues/40594).
  3171  
  3172  * Match `define` to strings in index expressions ([#2050](https://github.com/evanw/esbuild/issues/2050))
  3173  
  3174      With this release, configuring `--define:foo.bar=baz` now matches and replaces both `foo.bar` and `foo['bar']` expressions in the original source code. This is necessary for people who have enabled TypeScript's [`noPropertyAccessFromIndexSignature` feature](https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature), which prevents you from using normal property access syntax on a type with an index signature such as in the following code:
  3175  
  3176      ```ts
  3177      declare let foo: { [key: string]: any }
  3178      foo.bar // This is a type error if noPropertyAccessFromIndexSignature is enabled
  3179      foo['bar']
  3180      ```
  3181  
  3182      Previously esbuild would generate the following output with `--define:foo.bar=baz`:
  3183  
  3184      ```js
  3185      baz;
  3186      foo["bar"];
  3187      ```
  3188  
  3189      Now esbuild will generate the following output instead:
  3190  
  3191      ```js
  3192      baz;
  3193      baz;
  3194      ```
  3195  
  3196  * Add `--mangle-quoted` to mangle quoted properties ([#218](https://github.com/evanw/esbuild/issues/218))
  3197  
  3198      The `--mangle-props=` flag tells esbuild to automatically rename all properties matching the provided regular expression to shorter names to save space. Previously esbuild never modified the contents of string literals. In particular, `--mangle-props=_` would mangle `foo._bar` but not `foo['_bar']`. There are some coding patterns where renaming quoted property names is desirable, such as when using TypeScript's [`noPropertyAccessFromIndexSignature` feature](https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature) or when using TypeScript's [discriminated union narrowing behavior](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions):
  3199  
  3200      ```ts
  3201      interface Foo { _foo: string }
  3202      interface Bar { _bar: number }
  3203      declare const value: Foo | Bar
  3204      console.log('_foo' in value ? value._foo : value._bar)
  3205      ```
  3206  
  3207      The `'_foo' in value` check tells TypeScript to narrow the type of `value` to `Foo` in the true branch and to `Bar` in the false branch. Previously esbuild didn't mangle the property name `'_foo'` because it was inside a string literal. With this release, you can now use `--mangle-quoted` to also rename property names inside string literals:
  3208  
  3209      ```js
  3210      // Old output (with --mangle-props=_)
  3211      console.log("_foo" in value ? value.a : value.b);
  3212  
  3213      // New output (with --mangle-props=_ --mangle-quoted)
  3214      console.log("a" in value ? value.a : value.b);
  3215      ```
  3216  
  3217  * Parse and discard TypeScript `export as namespace` statements ([#2070](https://github.com/evanw/esbuild/issues/2070))
  3218  
  3219      TypeScript `.d.ts` type declaration files can sometimes contain statements of the form `export as namespace foo;`. I believe these serve to declare that the module adds a property of that name to the global object. You aren't supposed to feed `.d.ts` files to esbuild so this normally doesn't matter, but sometimes esbuild can end up having to parse them. One such case is if you import a type-only package who's `main` field in `package.json` is a `.d.ts` file.
  3220  
  3221      Previously esbuild only allowed `export as namespace` statements inside a `declare` context:
  3222  
  3223      ```ts
  3224      declare module Foo {
  3225        export as namespace foo;
  3226      }
  3227      ```
  3228  
  3229      Now esbuild will also allow these statements outside of a `declare` context:
  3230  
  3231      ```ts
  3232      export as namespace foo;
  3233      ```
  3234  
  3235      These statements are still just ignored and discarded.
  3236  
  3237  * Strip import assertions from unrecognized `import()` expressions ([#2036](https://github.com/evanw/esbuild/issues/2036))
  3238  
  3239      The new "import assertions" JavaScript language feature adds an optional second argument to dynamic `import()` expressions, which esbuild does support. However, this optional argument must be stripped when targeting older JavaScript environments for which this second argument would be a syntax error. Previously esbuild failed to strip this second argument in cases when the first argument to `import()` wasn't a string literal. This problem is now fixed:
  3240  
  3241      ```js
  3242      // Original code
  3243      console.log(import(foo, { assert: { type: 'json' } }))
  3244  
  3245      // Old output (with --target=es6)
  3246      console.log(import(foo, { assert: { type: "json" } }));
  3247  
  3248      // New output (with --target=es6)
  3249      console.log(import(foo));
  3250      ```
  3251  
  3252  * Remove simplified statement-level literal expressions ([#2063](https://github.com/evanw/esbuild/issues/2063))
  3253  
  3254      With this release, esbuild now removes simplified statement-level expressions if the simplified result is a literal expression even when minification is disabled. Previously this was only done when minification is enabled. This change was only made because some people are bothered by seeing top-level literal expressions. This change has no effect on code behavior.
  3255  
  3256  * Ignore `.d.ts` rules in `paths` in `tsconfig.json` files ([#2074](https://github.com/evanw/esbuild/issues/2074), [#2075](https://github.com/evanw/esbuild/pull/2075))
  3257  
  3258      TypeScript's `tsconfig.json` configuration file has a `paths` field that lets you remap import paths to alternative files on the file system. This field is interpreted by esbuild during bundling so that esbuild's behavior matches that of the TypeScript type checker. However, people sometimes override import paths to JavaScript files to instead point to a `.d.ts` TypeScript type declaration file for that JavaScript file. The intent of this is to just use the remapping for type information and not to actually import the `.d.ts` file during the build.
  3259  
  3260      With this release, esbuild will now ignore rules in `paths` that result in a `.d.ts` file during path resolution. This means code that does this should now be able to be bundled without modifying its `tsconfig.json` file to remove the `.d.ts` rule. This change was contributed by [@magic-akari](https://github.com/magic-akari).
  3261  
  3262  * Disable Go compiler optimizations for the Linux RISC-V 64bit build ([#2035](https://github.com/evanw/esbuild/pull/2035))
  3263  
  3264      Go's RISC-V 64bit compiler target has a fatal compiler optimization bug that causes esbuild to crash when it's run: https://github.com/golang/go/issues/51101. As a temporary workaround until a version of the Go compiler with the fix is published, Go compiler optimizations have been disabled for RISC-V. The 7.7mb esbuild binary executable for RISC-V is now 8.7mb instead. This workaround was contributed by [@piggynl](https://github.com/piggynl).
  3265  
  3266  ## 0.14.23
  3267  
  3268  * Update feature database to indicate that node 16.14+ supports import assertions ([#2030](https://github.com/evanw/esbuild/issues/2030))
  3269  
  3270      Node versions 16.14 and above now support import assertions according to [these release notes](https://github.com/nodejs/node/blob/6db686710ee1579452b2908a7a41b91cb729b944/doc/changelogs/CHANGELOG_V16.md#16.14.0). This release updates esbuild's internal feature compatibility database with this information, so esbuild no longer strips import assertions with `--target=node16.14`:
  3271  
  3272      ```js
  3273      // Original code
  3274      import data from './package.json' assert { type: 'json' }
  3275      console.log(data)
  3276  
  3277      // Old output (with --target=node16.14)
  3278      import data from "./package.json";
  3279      console.log(data);
  3280  
  3281      // New output (with --target=node16.14)
  3282      import data from "./package.json" assert { type: "json" };
  3283      console.log(data);
  3284      ```
  3285  
  3286  * Basic support for CSS `@layer` rules ([#2027](https://github.com/evanw/esbuild/issues/2027))
  3287  
  3288      This adds basic parsing support for a new CSS feature called `@layer` that changes how the CSS cascade works. Adding parsing support for this rule to esbuild means esbuild can now minify the contents of `@layer` rules:
  3289  
  3290      ```css
  3291      /* Original code */
  3292      @layer a {
  3293        @layer b {
  3294          div {
  3295            color: yellow;
  3296            margin: 0.0px;
  3297          }
  3298        }
  3299      }
  3300  
  3301      /* Old output (with --minify) */
  3302      @layer a{@layer b {div {color: yellow; margin: 0px;}}}
  3303  
  3304      /* New output (with --minify) */
  3305      @layer a.b{div{color:#ff0;margin:0}}
  3306      ```
  3307  
  3308      You can read more about `@layer` here:
  3309  
  3310      * Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
  3311      * Motivation: https://developer.chrome.com/blog/cascade-layers/
  3312  
  3313      Note that the support added in this release is only for parsing and printing `@layer` rules. The bundler does not yet know about these rules and bundling with `@layer` may result in behavior changes since these new rules have unusual ordering constraints that behave differently than all other CSS rules. Specifically the order is derived from the _first_ instance while with every other CSS rule, the order is derived from the _last_ instance.
  3314  
  3315  ## 0.14.22
  3316  
  3317  * Preserve whitespace for token lists that look like CSS variable declarations ([#2020](https://github.com/evanw/esbuild/issues/2020))
  3318  
  3319      Previously esbuild removed the whitespace after the CSS variable declaration in the following CSS:
  3320  
  3321      ```css
  3322      /* Original input */
  3323      @supports (--foo: ){html{background:green}}
  3324  
  3325      /* Previous output */
  3326      @supports (--foo:){html{background:green}}
  3327      ```
  3328  
  3329      However, that broke rendering in Chrome as it caused Chrome to ignore the entire rule. This did not break rendering in Firefox and Safari, so there's a browser bug either with Chrome or with both Firefox and Safari. In any case, esbuild now preserves whitespace after the CSS variable declaration in this case.
  3330  
  3331  * Ignore legal comments when merging adjacent duplicate CSS rules ([#2016](https://github.com/evanw/esbuild/issues/2016))
  3332  
  3333      This release now generates more compact minified CSS when there are legal comments in between two adjacent rules with identical content:
  3334  
  3335      ```css
  3336      /* Original code */
  3337      a { color: red }
  3338      /* @preserve */
  3339      b { color: red }
  3340  
  3341      /* Old output (with --minify) */
  3342      a{color:red}/* @preserve */b{color:red}
  3343  
  3344      /* New output (with --minify) */
  3345      a,b{color:red}/* @preserve */
  3346      ```
  3347  
  3348  * Block `onResolve` and `onLoad` until `onStart` ends ([#1967](https://github.com/evanw/esbuild/issues/1967))
  3349  
  3350      This release changes the semantics of the `onStart` callback. All `onStart` callbacks from all plugins are run concurrently so that a slow plugin doesn't hold up the entire build. That's still the case. However, previously the only thing waiting for the `onStart` callbacks to finish was the end of the build. This meant that `onResolve` and/or `onLoad` callbacks could sometimes run before `onStart` had finished. This was by design but violated user expectations. With this release, all `onStart` callbacks must finish before any `onResolve` and/or `onLoad` callbacks are run.
  3351  
  3352  * Add a self-referential `default` export to the JS API ([#1897](https://github.com/evanw/esbuild/issues/1897))
  3353  
  3354      Some people try to use esbuild's API using `import esbuild from 'esbuild'` instead of `import * as esbuild from 'esbuild'` (i.e. using a default import instead of a namespace import). There is no `default` export so that wasn't ever intended to work. But it would work sometimes depending on which tools you used and how they were configured so some people still wrote code this way. This release tries to make that work by adding a self-referential `default` export that is equal to esbuild's module namespace object.
  3355  
  3356      More detail: The published package for esbuild's JS API is in CommonJS format, although the source code for esbuild's JS API is in ESM format. The original ESM code for esbuild's JS API has no export named `default` so using a default import like this doesn't work with Babel-compatible toolchains (since they respect the semantics of the original ESM code). However, it happens to work with node-compatible toolchains because node's implementation of importing CommonJS from ESM broke compatibility with existing conventions and automatically creates a `default` export which is set to `module.exports`. This is an unfortunate compatibility headache because it means the `default` import only works sometimes. This release tries to fix this by explicitly creating a self-referential `default` export. It now doesn't matter if you do `esbuild.build()`, `esbuild.default.build()`, or `esbuild.default.default.build()` because they should all do the same thing. Hopefully this means people don't have to deal with this problem anymore.
  3357  
  3358  * Handle `write` errors when esbuild's child process is killed ([#2007](https://github.com/evanw/esbuild/issues/2007))
  3359  
  3360      If you type Ctrl+C in a terminal when a script that uses esbuild's JS library is running, esbuild's child process may be killed before the parent process. In that case calls to the `write()` syscall may fail with an `EPIPE` error. Previously this resulted in an uncaught exception because esbuild didn't handle this case. Starting with this release, esbuild should now catch these errors and redirect them into a general `The service was stopped` error which should be returned from whatever top-level API calls were in progress.
  3361  
  3362  * Better error message when browser WASM bugs are present ([#1863](https://github.com/evanw/esbuild/issues/1863))
  3363  
  3364      Safari's WebAssembly implementation appears to be broken somehow, at least when running esbuild. Sometimes this manifests as a stack overflow and sometimes as a Go panic. Previously a Go panic resulted in the error message `Can't find variable: fs` but this should now result in the Go panic being printed to the console. Using esbuild's WebAssembly library in Safari is still broken but now there's a more helpful error message.
  3365  
  3366      More detail: When Go panics, it prints a stack trace to stderr (i.e. file descriptor 2). Go's WebAssembly shim calls out to node's `fs.writeSync()` function to do this, and it converts calls to `fs.writeSync()` into calls to `console.log()` in the browser by providing a shim for `fs`. However, Go's shim code stores the shim on `window.fs` in the browser. This is undesirable because it pollutes the global scope and leads to brittle code that can break if other code also uses `window.fs`. To avoid this, esbuild shadows the global object by wrapping Go's shim. But that broke bare references to `fs` since the shim is no longer stored on `window.fs`. This release now stores the shim in a local variable named `fs` so that bare references to `fs` work correctly.
  3367  
  3368  * Undo incorrect dead-code elimination with destructuring ([#1183](https://github.com/evanw/esbuild/issues/1183))
  3369  
  3370      Previously esbuild eliminated these statements as dead code if tree-shaking was enabled:
  3371  
  3372      ```js
  3373      let [a] = {}
  3374      let { b } = null
  3375      ```
  3376  
  3377      This is incorrect because both of these lines will throw an error when evaluated. With this release, esbuild now preserves these statements even when tree shaking is enabled.
  3378  
  3379  * Update to Go 1.17.7
  3380  
  3381      The version of the Go compiler used to compile esbuild has been upgraded from Go 1.17.6 to Go 1.17.7, which contains a few [compiler and security bug fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.17.7+label%3ACherryPickApproved).
  3382  
  3383  ## 0.14.21
  3384  
  3385  * Handle an additional `browser` map edge case ([#2001](https://github.com/evanw/esbuild/pull/2001), [#2002](https://github.com/evanw/esbuild/issues/2002))
  3386  
  3387      There is a community convention around the `browser` field in `package.json` that allows remapping import paths within a package when the package is bundled for use within a browser. There isn't a rigorous definition of how it's supposed to work and every bundler implements it differently. The approach esbuild uses is to try to be "maximally compatible" in that if at least one bundler exhibits a particular behavior regarding the `browser` map that allows a mapping to work, then esbuild also attempts to make that work.
  3388  
  3389      I have a collection of test cases for this going here: https://github.com/evanw/package-json-browser-tests. However, I was missing test coverage for the edge case where a package path import in a subdirectory of the package could potentially match a remapping. The "maximally compatible" approach means replicating bugs in Browserify's implementation of the feature where package paths are mistaken for relative paths and are still remapped. Here's a specific example of an edge case that's now handled:
  3390  
  3391      * `entry.js`:
  3392  
  3393          ```js
  3394          require('pkg/sub')
  3395          ```
  3396  
  3397      * `node_modules/pkg/package.json`:
  3398  
  3399          ```json
  3400          {
  3401            "browser": {
  3402              "./sub": "./sub/foo.js",
  3403              "./sub/sub": "./sub/bar.js"
  3404            }
  3405          }
  3406          ```
  3407  
  3408      * `node_modules/pkg/sub/foo.js`:
  3409  
  3410          ```js
  3411          require('sub')
  3412          ```
  3413  
  3414      * `node_modules/pkg/sub/bar.js`:
  3415  
  3416          ```js
  3417          console.log('works')
  3418          ```
  3419  
  3420      The import path `sub` in `require('sub')` is mistaken for a relative path by Browserify due to a bug in Browserify, so Browserify treats it as if it were `./sub` instead. This is a Browserify-specific behavior and currently doesn't happen in any other bundler (except for esbuild, which attempts to replicate Browserify's bug).
  3421  
  3422      Previously esbuild was incorrectly resolving `./sub` relative to the top-level package directory instead of to the subdirectory in this case, which meant `./sub` was incorrectly matching `"./sub": "./sub/foo.js"` instead of `"./sub/sub": "./sub/bar.js"`. This has been fixed so esbuild can now emulate Browserify's bug correctly in this edge case.
  3423  
  3424  * Support for esbuild with Linux on RISC-V 64bit ([#2000](https://github.com/evanw/esbuild/pull/2000))
  3425  
  3426      With this release, esbuild now has a published binary executable for the RISC-V 64bit architecture in the [`esbuild-linux-riscv64`](https://www.npmjs.com/package/esbuild-linux-riscv64) npm package. This change was contributed by [@piggynl](https://github.com/piggynl).
  3427  
  3428  ## 0.14.20
  3429  
  3430  * Fix property mangling and keyword properties ([#1998](https://github.com/evanw/esbuild/issues/1998))
  3431  
  3432      Previously enabling property mangling with `--mangle-props=` failed to add a space before property names after a keyword. This bug has been fixed:
  3433  
  3434      ```js
  3435      // Original code
  3436      class Foo {
  3437        static foo = {
  3438          get bar() {}
  3439        }
  3440      }
  3441  
  3442      // Old output (with --minify --mangle-props=.)
  3443      class Foo{statics={gett(){}}}
  3444  
  3445      // New output (with --minify --mangle-props=.)
  3446      class Foo{static s={get t(){}}}
  3447      ```
  3448  
  3449  ## 0.14.19
  3450  
  3451  * Special-case `const` inlining at the top of a scope ([#1317](https://github.com/evanw/esbuild/issues/1317), [#1981](https://github.com/evanw/esbuild/issues/1981))
  3452  
  3453      The minifier now inlines `const` variables (even across modules during bundling) if a certain set of specific requirements are met:
  3454  
  3455      * All `const` variables to be inlined are at the top of their scope
  3456      * That scope doesn't contain any `import` or `export` statements with paths
  3457      * All constants to be inlined are `null`, `undefined`, `true`, `false`, an integer, or a short real number
  3458      * Any expression outside of a small list of allowed ones stops constant identification
  3459  
  3460      Practically speaking this basically means that you can trigger this optimization by just putting the constants you want inlined into a separate file (e.g. `constants.js`) and bundling everything together.
  3461  
  3462      These specific conditions are present to avoid esbuild unintentionally causing any behavior changes by inlining constants when the variable reference could potentially be evaluated before being declared. It's possible to identify more cases where constants can be inlined but doing so may require complex call graph analysis so it has not been implemented. Although these specific heuristics may change over time, this general approach to constant inlining should continue to work going forward.
  3463  
  3464      Here's an example:
  3465  
  3466      ```js
  3467      // Original code
  3468      const bold = 1 << 0;
  3469      const italic = 1 << 1;
  3470      const underline = 1 << 2;
  3471      const font = bold | italic | underline;
  3472      console.log(font);
  3473  
  3474      // Old output (with --minify --bundle)
  3475      (()=>{var o=1<<0,n=1<<1,c=1<<2,t=o|n|c;console.log(t);})();
  3476  
  3477      // New output (with --minify --bundle)
  3478      (()=>{console.log(7);})();
  3479      ```
  3480  
  3481  ## 0.14.18
  3482  
  3483  * Add the `--mangle-cache=` feature ([#1977](https://github.com/evanw/esbuild/issues/1977))
  3484  
  3485      This release adds a cache API for the newly-released `--mangle-props=` feature. When enabled, all mangled property renamings are recorded in the cache during the initial build. Subsequent builds reuse the renamings stored in the cache and add additional renamings for any newly-added properties. This has a few consequences:
  3486  
  3487      * You can customize what mangled properties are renamed to by editing the cache before passing it to esbuild (the cache is a map of the original name to the mangled name).
  3488  
  3489      * The cache serves as a list of all properties that were mangled. You can easily scan it to see if there are any unexpected property renamings.
  3490  
  3491      * You can disable mangling for individual properties by setting the renamed value to `false` instead of to a string. This is similar to the `--reserve-props=` setting but on a per-property basis.
  3492  
  3493      * You can ensure consistent renaming between builds (e.g. a main-thread file and a web worker, or a library and a plugin). Without this feature, each build would do an independent renaming operation and the mangled property names likely wouldn't be consistent.
  3494  
  3495      Here's how to use it:
  3496  
  3497      * CLI
  3498  
  3499          ```sh
  3500          $ esbuild example.ts --mangle-props=_$ --mangle-cache=cache.json
  3501          ```
  3502  
  3503      * JS API
  3504  
  3505          ```js
  3506          let result = await esbuild.build({
  3507            entryPoints: ['example.ts'],
  3508            mangleProps: /_$/,
  3509            mangleCache: {
  3510              customRenaming_: '__c',
  3511              disabledRenaming_: false,
  3512            },
  3513          })
  3514          let updatedMangleCache = result.mangleCache
  3515          ```
  3516  
  3517      * Go API
  3518  
  3519          ```go
  3520          result := api.Build(api.BuildOptions{
  3521            EntryPoints: []string{"example.ts"},
  3522            MangleProps: "_$",
  3523            MangleCache: map[string]interface{}{
  3524              "customRenaming_":   "__c",
  3525              "disabledRenaming_": false,
  3526            },
  3527          })
  3528          updatedMangleCache := result.MangleCache
  3529          ```
  3530  
  3531      The above code would do something like the following:
  3532  
  3533      ```js
  3534      // Original code
  3535      x = {
  3536        customRenaming_: 1,
  3537        disabledRenaming_: 2,
  3538        otherProp_: 3,
  3539      }
  3540  
  3541      // Generated code
  3542      x = {
  3543        __c: 1,
  3544        disabledRenaming_: 2,
  3545        a: 3
  3546      };
  3547  
  3548      // Updated mangle cache
  3549      {
  3550        "customRenaming_": "__c",
  3551        "disabledRenaming_": false,
  3552        "otherProp_": "a"
  3553      }
  3554      ```
  3555  
  3556  * Add `opera` and `ie` as possible target environments
  3557  
  3558      You can now target [Opera](https://www.opera.com/) and/or [Internet Explorer](https://www.microsoft.com/en-us/download/internet-explorer.aspx) using the `--target=` setting. For example, `--target=opera45,ie9` targets Opera 45 and Internet Explorer 9. This change does not add any additional features to esbuild's code transformation pipeline to transform newer syntax so that it works in Internet Explorer. It just adds information about what features are supported in these browsers to esbuild's internal feature compatibility table.
  3559  
  3560  * Minify `typeof x !== 'undefined'` to `typeof x < 'u'`
  3561  
  3562      This release introduces a small improvement for code that does a lot of `typeof` checks against `undefined`:
  3563  
  3564      ```js
  3565      // Original code
  3566      y = typeof x !== 'undefined';
  3567  
  3568      // Old output (with --minify)
  3569      y=typeof x!="undefined";
  3570  
  3571      // New output (with --minify)
  3572      y=typeof x<"u";
  3573      ```
  3574  
  3575      This transformation is only active when minification is enabled, and is disabled if the language target is set lower than ES2020 or if Internet Explorer is set as a target environment. Before ES2020, implementations were allowed to return non-standard values from the `typeof` operator for a few objects. Internet Explorer took advantage of this to sometimes return the string `'unknown'` instead of `'undefined'`. But this has been removed from the specification and Internet Explorer was the only engine to do this, so this minification is valid for code that does not need to target Internet Explorer.
  3576  
  3577  ## 0.14.17
  3578  
  3579  * Attempt to fix an install script issue on Ubuntu Linux ([#1711](https://github.com/evanw/esbuild/issues/1711))
  3580  
  3581      There have been some reports of esbuild failing to install on Ubuntu Linux for a while now. I haven't been able to reproduce this myself due to lack of reproduction instructions until today, when I learned that the issue only happens when you install node from the [Snap Store](https://snapcraft.io/) instead of downloading the [official version of node](https://nodejs.org/dist/).
  3582  
  3583      The problem appears to be that when node is installed from the Snap Store, install scripts are run with stderr not being writable? This then appears to cause a problem for esbuild's install script when it uses `execFileSync` to validate that the esbuild binary is working correctly. This throws the error `EACCES: permission denied, write` even though this particular command never writes to stderr.
  3584  
  3585      Node's documentation says that stderr for `execFileSync` defaults to that of the parent process. Forcing it to `'pipe'` instead appears to fix the issue, although I still don't fully understand what's happening or why. I'm publishing this small change regardless to see if it fixes this install script edge case.
  3586  
  3587  * Avoid a syntax error due to `--mangle-props=.` and `super()` ([#1976](https://github.com/evanw/esbuild/issues/1976))
  3588  
  3589      This release fixes an issue where passing `--mangle-props=.` (i.e. telling esbuild to mangle every single property) caused a syntax error with code like this:
  3590  
  3591      ```js
  3592      class Foo {}
  3593      class Bar extends Foo {
  3594        constructor() {
  3595          super();
  3596        }
  3597      }
  3598      ```
  3599  
  3600      The problem was that `constructor` was being renamed to another method, which then made it no longer a constructor, which meant that `super()` was now a syntax error. I have added a workaround that avoids renaming any property named `constructor` so that esbuild doesn't generate a syntax error here.
  3601  
  3602      Despite this fix, I highly recommend not using `--mangle-props=.` because your code will almost certainly be broken. You will have to manually add every single property that you don't want mangled to `--reserve-props=` which is an excessive maintenance burden (e.g. reserve `parse` to use `JSON.parse`). Instead I recommend using a common pattern for all properties you intend to be mangled that is unlikely to appear in the APIs you use such as "ends in an underscore." This is an opt-in approach instead of an opt-out approach. It also makes it obvious when reading the code which properties will be mangled and which ones won't be.
  3603  
  3604  ## 0.14.16
  3605  
  3606  * Support property name mangling with some TypeScript syntax features
  3607  
  3608      The newly-released `--mangle-props=` feature previously only affected JavaScript syntax features. This release adds support for using mangle props with certain TypeScript syntax features:
  3609  
  3610      * **TypeScript parameter properties**
  3611  
  3612          Parameter properties are a TypeScript-only shorthand way of initializing a class field directly from the constructor argument list. Previously parameter properties were not treated as properties to be mangled. They should now be handled correctly:
  3613  
  3614          ```ts
  3615          // Original code
  3616          class Foo {
  3617            constructor(public foo_) {}
  3618          }
  3619          new Foo().foo_;
  3620  
  3621          // Old output (with --minify --mangle-props=_)
  3622          class Foo{constructor(c){this.foo_=c}}new Foo().o;
  3623  
  3624          // New output (with --minify --mangle-props=_)
  3625          class Foo{constructor(o){this.c=o}}new Foo().c;
  3626          ```
  3627  
  3628      * **TypeScript namespaces**
  3629  
  3630          Namespaces are a TypeScript-only way to add properties to an object. Previously exported namespace members were not treated as properties to be mangled. They should now be handled correctly:
  3631  
  3632          ```ts
  3633          // Original code
  3634          namespace ns {
  3635            export let foo_ = 1;
  3636            export function bar_(x) {}
  3637          }
  3638          ns.bar_(ns.foo_);
  3639  
  3640          // Old output (with --minify --mangle-props=_)
  3641          var ns;(e=>{e.foo_=1;function t(a){}e.bar_=t})(ns||={}),ns.e(ns.o);
  3642  
  3643          // New output (with --minify --mangle-props=_)
  3644          var ns;(e=>{e.e=1;function o(p){}e.t=o})(ns||={}),ns.t(ns.e);
  3645          ```
  3646  
  3647  * Fix property name mangling for lowered class fields
  3648  
  3649      This release fixes a compiler crash with `--mangle-props=` and class fields that need to be transformed to older versions of JavaScript. The problem was that doing this is an unusual case where the mangled property name must be represented as a string instead of as a property name, which previously wasn't implemented. This case should now work correctly:
  3650  
  3651      ```js
  3652      // Original code
  3653      class Foo {
  3654        static foo_;
  3655      }
  3656      Foo.foo_ = 0;
  3657  
  3658      // New output (with --mangle-props=_ --target=es6)
  3659      class Foo {
  3660      }
  3661      __publicField(Foo, "a");
  3662      Foo.a = 0;
  3663      ```
  3664  
  3665  ## 0.14.15
  3666  
  3667  * Add property name mangling with `--mangle-props=` ([#218](https://github.com/evanw/esbuild/issues/218))
  3668  
  3669      ⚠️ **Using this feature can break your code in subtle ways.** Do not use this feature unless you know what you are doing, and you know exactly how it will affect both your code and all of your dependencies. ⚠️
  3670  
  3671      This release introduces property name mangling, which is similar to an existing feature from the popular [UglifyJS](github.com/mishoo/uglifyjs) and [Terser](github.com/terser/terser) JavaScript minifiers. This setting lets you pass a regular expression to esbuild to tell esbuild to automatically rename all properties that match this regular expression. It's useful when you want to minify certain property names in your code either to make the generated code smaller or to somewhat obfuscate your code's intent.
  3672  
  3673      Here's an example that uses the regular expression `_$` to mangle all properties ending in an underscore, such as `foo_`:
  3674  
  3675      ```
  3676      $ echo 'console.log({ foo_: 0 }.foo_)' | esbuild --mangle-props=_$
  3677      console.log({ a: 0 }.a);
  3678      ```
  3679  
  3680      Only mangling properties that end in an underscore is a reasonable heuristic because normal JS code doesn't typically contain identifiers like that. Browser APIs also don't use this naming convention so this also avoids conflicts with browser APIs. If you want to avoid mangling names such as [`__defineGetter__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__) you could consider using a more complex regular expression such as `[^_]_$` (i.e. must end in a non-underscore followed by an underscore).
  3681  
  3682      This is a separate setting instead of being part of the minify setting because it's an unsafe transformation that does not work on arbitrary JavaScript code. It only works if the provided regular expression matches all of the properties that you want mangled and does not match any of the properties that you don't want mangled. It also only works if you do not under any circumstances reference a property name to be mangled as a string. For example, it means you can't use `Object.defineProperty(obj, 'prop', ...)` or `obj['prop']` with a mangled property. Specifically the following syntax constructs are the only ones eligible for property mangling:
  3683  
  3684      | Syntax                          | Example                 |
  3685      |---------------------------------|-------------------------|
  3686      | Dot property access             | `x.foo_`                |
  3687      | Dot optional chain              | `x?.foo_`               |
  3688      | Object properties               | `x = { foo_: y }`       |
  3689      | Object methods                  | `x = { foo_() {} }`     |
  3690      | Class fields                    | `class x { foo_ = y }`  |
  3691      | Class methods                   | `class x { foo_() {} }` |
  3692      | Object destructuring binding    | `let { foo_: x } = y`   |
  3693      | Object destructuring assignment | `({ foo_: x } = y)`     |
  3694      | JSX element names               | `<X.foo_></X.foo_>`     |
  3695      | JSX attribute names             | `<X foo_={y} />`        |
  3696  
  3697      You can avoid property mangling for an individual property by quoting it as a string. However, you must consistently use quotes or no quotes for a given property everywhere for this to work. For example, `print({ foo_: 0 }.foo_)` will be mangled into `print({ a: 0 }.a)` while `print({ 'foo_': 0 }['foo_'])` will not be mangled.
  3698  
  3699      When using this feature, keep in mind that property names are only consistently mangled within a single esbuild API call but not across esbuild API calls. Each esbuild API call does an independent property mangling operation so output files generated by two different API calls may mangle the same property to two different names, which could cause the resulting code to behave incorrectly.
  3700  
  3701      If you would like to exclude certain properties from mangling, you can reserve them with the `--reserve-props=` setting. For example, this uses the regular expression `^__.*__$` to reserve all properties that start and end with two underscores, such as `__foo__`:
  3702  
  3703      ```
  3704      $ echo 'console.log({ __foo__: 0 }.__foo__)' | esbuild --mangle-props=_$
  3705      console.log({ a: 0 }.a);
  3706  
  3707      $ echo 'console.log({ __foo__: 0 }.__foo__)' | esbuild --mangle-props=_$ "--reserve-props=^__.*__$"
  3708      console.log({ __foo__: 0 }.__foo__);
  3709      ```
  3710  
  3711  * Mark esbuild as supporting node v12+ ([#1970](https://github.com/evanw/esbuild/issues/1970))
  3712  
  3713      Someone requested that esbuild populate the `engines.node` field in `package.json`. This release adds the following to each `package.json` file that esbuild publishes:
  3714  
  3715      ```json
  3716      "engines": {
  3717        "node": ">=12"
  3718      },
  3719      ```
  3720  
  3721      This was chosen because it's the oldest version of node that's currently still receiving support from the node team, and so is the oldest version of node that esbuild supports: https://nodejs.org/en/about/releases/.
  3722  
  3723  * Remove error recovery for invalid `//` comments in CSS ([#1965](https://github.com/evanw/esbuild/issues/1965))
  3724  
  3725      Previously esbuild treated `//` as a comment in CSS and generated a warning, even though comments in CSS use `/* ... */` instead. This allowed you to run esbuild on CSS intended for certain CSS preprocessors that support single-line comments.
  3726  
  3727      However, some people are changing from another build tool to esbuild and have a code base that relies on `//` being preserved even though it's nonsense CSS and causes the entire surrounding rule to be discarded by the browser. Presumably this nonsense CSS ended up there at some point due to an incorrectly-configured build pipeline and the site now relies on that entire rule being discarded. If esbuild interprets `//` as a comment, it could cause the rule to no longer be discarded or even cause something else to happen.
  3728  
  3729      With this release, esbuild no longer treats `//` as a comment in CSS. It still warns about it but now passes it through unmodified. This means it's no longer possible to run esbuild on CSS code containing single-line comments but it means that esbuild's behavior regarding these nonsensical CSS rules more accurately represents what happens in a browser.
  3730  
  3731  ## 0.14.14
  3732  
  3733  * Fix bug with filename hashes and the `file` loader ([#1957](https://github.com/evanw/esbuild/issues/1957))
  3734  
  3735      This release fixes a bug where if a file name template has the `[hash]` placeholder (either `--entry-names=` or `--chunk-names=`), the hash that esbuild generates didn't include the content of the string generated by the `file` loader. Importing a file with the `file` loader causes the imported file to be copied to the output directory and causes the imported value to be the relative path from the output JS file to that copied file. This bug meant that if the `--asset-names=` setting also contained `[hash]` and the file loaded with the `file` loader was changed, the hash in the copied file name would change but the hash of the JS file would not change, which could potentially result in a stale JS file being loaded. Now the hash of the JS file will be changed too which fixes the reload issue.
  3736  
  3737  * Prefer the `import` condition for entry points ([#1956](https://github.com/evanw/esbuild/issues/1956))
  3738  
  3739      The `exports` field in `package.json` maps package subpaths to file paths. The mapping can be conditional, which lets it vary in different situations. For example, you can have an `import` condition that applies when the subpath originated from a JS import statement, and a `require` condition that applies when the subpath originated from a JS require call. These are supposed to be mutually exclusive according to the specification: https://nodejs.org/api/packages.html#conditional-exports.
  3740  
  3741      However, there's a situation with esbuild where it's not immediately obvious which one should be applied: when a package name is specified as an entry point. For example, this can happen if you do `esbuild --bundle some-pkg` on the command line. In this situation `some-pkg` does not originate from either a JS import statement or a JS require call. Previously esbuild just didn't apply the `import` or `require` conditions. But that could result in path resolution failure if the package doesn't provide a back-up `default` condition, as is the case with the `is-plain-object` package.
  3742  
  3743      Starting with this release, esbuild will now use the `import` condition in this case. This appears to be how Webpack and Rollup handle this situation so this change makes esbuild consistent with other tools in the ecosystem. Parcel (the other major bundler) just doesn't handle this case at all so esbuild's behavior is not at odds with Parcel's behavior here.
  3744  
  3745  * Make parsing of invalid `@keyframes` rules more robust ([#1959](https://github.com/evanw/esbuild/issues/1959))
  3746  
  3747      This improves esbuild's parsing of certain malformed `@keyframes` rules to avoid them affecting the following rule. This fix only affects invalid CSS files, and does not change any behavior for files containing valid CSS. Here's an example of the fix:
  3748  
  3749      ```css
  3750      /* Original code */
  3751      @keyframes x { . }
  3752      @keyframes y { 1% { a: b; } }
  3753  
  3754      /* Old output (with --minify) */
  3755      @keyframes x{y{1% {a: b;}}}
  3756  
  3757      /* New output (with --minify) */
  3758      @keyframes x{.}@keyframes y{1%{a:b}}
  3759      ```
  3760  
  3761  ## 0.14.13
  3762  
  3763  * Be more consistent about external paths ([#619](https://github.com/evanw/esbuild/issues/619))
  3764  
  3765      The rules for marking paths as external using `--external:` grew over time as more special-cases were added. This release reworks the internal representation to be more straightforward and robust. A side effect is that wildcard patterns can now match post-resolve paths in addition to pre-resolve paths. Specifically you can now do `--external:./node_modules/*` to mark all files in the `./node_modules/` directory as external.
  3766  
  3767      This is the updated logic:
  3768  
  3769      * Before path resolution begins, import paths are checked against everything passed via an `--external:` flag. In addition, if something looks like a package path (i.e. doesn't start with `/` or `./` or `../`), import paths are checked to see if they have that package path as a path prefix (so `--external:@foo/bar` matches the import path `@foo/bar/baz`).
  3770  
  3771      * After path resolution ends, the absolute paths are checked against everything passed via `--external:` that doesn't look like a package path (i.e. that starts with `/` or `./` or `../`). But before checking, the pattern is transformed to be relative to the current working directory.
  3772  
  3773  * Attempt to explain why esbuild can't run ([#1819](https://github.com/evanw/esbuild/issues/1819))
  3774  
  3775      People sometimes try to install esbuild on one OS and then copy the `node_modules` directory over to another OS without reinstalling. This works with JavaScript code but doesn't work with esbuild because esbuild is a native binary executable. This release attempts to offer a helpful error message when this happens. It looks like this:
  3776  
  3777      ```
  3778      $ ./node_modules/.bin/esbuild
  3779      ./node_modules/esbuild/bin/esbuild:106
  3780                throw new Error(`
  3781                ^
  3782  
  3783      Error:
  3784      You installed esbuild on another platform than the one you're currently using.
  3785      This won't work because esbuild is written with native code and needs to
  3786      install a platform-specific binary executable.
  3787  
  3788      Specifically the "esbuild-linux-arm64" package is present but this platform
  3789      needs the "esbuild-darwin-arm64" package instead. People often get into this
  3790      situation by installing esbuild on Windows or macOS and copying "node_modules"
  3791      into a Docker image that runs Linux, or by copying "node_modules" between
  3792      Windows and WSL environments.
  3793  
  3794      If you are installing with npm, you can try not copying the "node_modules"
  3795      directory when you copy the files over, and running "npm ci" or "npm install"
  3796      on the destination platform after the copy. Or you could consider using yarn
  3797      instead which has built-in support for installing a package on multiple
  3798      platforms simultaneously.
  3799  
  3800      If you are installing with yarn, you can try listing both this platform and the
  3801      other platform in your ".yarnrc.yml" file using the "supportedArchitectures"
  3802      feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures
  3803      Keep in mind that this means multiple copies of esbuild will be present.
  3804  
  3805      Another alternative is to use the "esbuild-wasm" package instead, which works
  3806      the same way on all platforms. But it comes with a heavy performance cost and
  3807      can sometimes be 10x slower than the "esbuild" package, so you may also not
  3808      want to do that.
  3809  
  3810          at generateBinPath (./node_modules/esbuild/bin/esbuild:106:17)
  3811          at Object.<anonymous> (./node_modules/esbuild/bin/esbuild:161:39)
  3812          at Module._compile (node:internal/modules/cjs/loader:1101:14)
  3813          at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
  3814          at Module.load (node:internal/modules/cjs/loader:981:32)
  3815          at Function.Module._load (node:internal/modules/cjs/loader:822:12)
  3816          at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
  3817          at node:internal/main/run_main_module:17:47
  3818      ```
  3819  
  3820  ## 0.14.12
  3821  
  3822  * Ignore invalid `@import` rules in CSS ([#1946](https://github.com/evanw/esbuild/issues/1946))
  3823  
  3824      In CSS, `@import` rules must come first before any other kind of rule (except for `@charset` rules). Previously esbuild would warn about incorrectly ordered `@import` rules and then hoist them to the top of the file. This broke people who wrote invalid `@import` rules in the middle of their files and then relied on them being ignored. With this release, esbuild will now ignore invalid `@import` rules and pass them through unmodified. This more accurately follows the CSS specification. Note that this behavior differs from other tools like Parcel, which does hoist CSS `@import` rules.
  3825  
  3826  * Print invalid CSS differently ([#1947](https://github.com/evanw/esbuild/issues/1947))
  3827  
  3828      This changes how esbuild prints nested `@import` statements that are missing a trailing `;`, which is invalid CSS. The result is still partially invalid CSS, but now printed in a better-looking way:
  3829  
  3830      ```css
  3831      /* Original code */
  3832      .bad { @import url("other") }
  3833      .red { background: red; }
  3834  
  3835      /* Old output (with --minify) */
  3836      .bad{@import url(other) } .red{background: red;}}
  3837  
  3838      /* New output (with --minify) */
  3839      .bad{@import url(other);}.red{background:red}
  3840      ```
  3841  
  3842  * Warn about CSS nesting syntax ([#1945](https://github.com/evanw/esbuild/issues/1945))
  3843  
  3844      There's a proposed [CSS syntax for nesting rules](https://drafts.csswg.org/css-nesting/) using the `&` selector, but it's not currently implemented in any browser. Previously esbuild silently passed the syntax through untransformed. With this release, esbuild will now warn when you use nesting syntax with a `--target=` setting that includes a browser.
  3845  
  3846  * Warn about `}` and `>` inside JSX elements
  3847  
  3848      The `}` and `>` characters are invalid inside JSX elements according to [the JSX specification](https://facebook.github.io/jsx/) because they commonly result from typos like these that are hard to catch in code reviews:
  3849  
  3850      ```jsx
  3851      function F() {
  3852        return <div>></div>;
  3853      }
  3854      function G() {
  3855        return <div>{1}}</div>;
  3856      }
  3857      ```
  3858  
  3859      The TypeScript compiler already [treats this as an error](https://github.com/microsoft/TypeScript/issues/36341), so esbuild now treats this as an error in TypeScript files too. That looks like this:
  3860  
  3861      ```
  3862      ✘ [ERROR] The character ">" is not valid inside a JSX element
  3863  
  3864          example.tsx:2:14:
  3865            2 │   return <div>></div>;
  3866              │               ^
  3867              ╵               {'>'}
  3868  
  3869        Did you mean to escape it as "{'>'}" instead?
  3870  
  3871      ✘ [ERROR] The character "}" is not valid inside a JSX element
  3872  
  3873          example.tsx:5:17:
  3874            5 │   return <div>{1}}</div>;
  3875              │                  ^
  3876              ╵                  {'}'}
  3877  
  3878        Did you mean to escape it as "{'}'}" instead?
  3879      ```
  3880  
  3881      Babel doesn't yet treat this as an error, so esbuild only warns about these characters in JavaScript files for now. Babel 8 [treats this as an error](https://github.com/babel/babel/issues/11042) but Babel 8 [hasn't been released yet](https://github.com/babel/babel/issues/10746). If you see this warning, I recommend fixing the invalid JSX syntax because it will become an error in the future.
  3882  
  3883  * Warn about basic CSS property typos
  3884  
  3885      This release now generates a warning if you use a CSS property that is one character off from a known CSS property:
  3886  
  3887      ```
  3888      ▲ [WARNING] "marign-left" is not a known CSS property
  3889  
  3890          example.css:2:2:
  3891            2 │   marign-left: 12px;
  3892              │   ~~~~~~~~~~~
  3893              ╵   margin-left
  3894  
  3895        Did you mean "margin-left" instead?
  3896      ```
  3897  
  3898  ## 0.14.11
  3899  
  3900  * Fix a bug with enum inlining ([#1903](https://github.com/evanw/esbuild/issues/1903))
  3901  
  3902      The new TypeScript enum inlining behavior had a bug where it worked correctly if you used `export enum Foo` but not if you used `enum Foo` and then later `export { Foo }`. This release fixes the bug so enum inlining now works correctly in this case.
  3903  
  3904  * Warn about `module.exports.foo = ...` in ESM ([#1907](https://github.com/evanw/esbuild/issues/1907))
  3905  
  3906      The `module` variable is treated as a global variable reference instead of as a CommonJS module reference in ESM code, which can cause problems for people that try to use both CommonJS and ESM exports in the same file. There has been a warning about this since version 0.14.9. However, the warning only covered cases like `exports.foo = bar` and `module.exports = bar` but not `module.exports.foo = bar`. This last case is now handled;
  3907  
  3908      ```
  3909      ▲ [WARNING] The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
  3910  
  3911          example.ts:2:0:
  3912            2 │ module.exports.b = 1
  3913              ╵ ~~~~~~
  3914  
  3915        This file is considered to be an ECMAScript module because of the "export" keyword here:
  3916  
  3917          example.ts:1:0:
  3918            1 │ export let a = 1
  3919              ╵ ~~~~~~
  3920      ```
  3921  
  3922  * Enable esbuild's CLI with Deno ([#1913](https://github.com/evanw/esbuild/issues/1913))
  3923  
  3924      This release allows you to use Deno as an esbuild installer, without also needing to use esbuild's JavaScript API. You can now use esbuild's CLI with Deno:
  3925  
  3926      ```
  3927      deno run --allow-all "https://deno.land/x/esbuild@v0.14.11/mod.js" --version
  3928      ```