Skip to content

Releases: evanw/esbuild

v0.11.20

08 May 00:58
Compare
Choose a tag to compare
  • Omit warning about duplicate JSON keys from inside node_modules (#1254)

    This release no longer warns about duplicate keys inside package.json files inside node_modules. There are packages like this that are published to npm, and this warning is unactionable. Now esbuild will only issue this warning outside of node_modules directories.

  • Add CSS minification for box-shadow values

    The CSS box-shadow property is now minified when --mangle-syntax is enabled. This includes trimming length values and minifying color representations.

  • Fix object spread transform for non-spread getters (#1259)

    When transforming an object literal containing object spread (the ... syntax), properties inside the spread should be evaluated but properties outside the spread should not be evaluated. Previously esbuild's object spread transform incorrectly evaluated properties in both cases. Consider this example:

    var obj = {
      ...{ get x() { console.log(1) } },
      get y() { console.log(3) },
    }
    console.log(2)
    obj.y

    This should print out 1 2 3 because the non-spread getter should not be evaluated. Instead, esbuild was incorrectly transforming this into code that printed 1 3 2. This issue should now be fixed with this release.

  • Prevent private class members from being added more than once

    This fixes a corner case with the private class member implementation. Constructors in JavaScript can return an object other than this, so private class members can actually be added to objects other than this. This can be abused to attach completely private metadata to other objects:

    class Base {
      constructor(x) {
        return x
      }
    }
    class Derived extends Base {
      #y
      static is(z) {
        return #y in z
      }
    }
    const foo = {}
    new Derived(foo)
    console.log(Derived.is(foo)) // true

    This already worked in code transformed by esbuild for older browsers. However, calling new Derived(foo) multiple times in the above code was incorrectly allowed. This should not be allowed because it would mean that the private field #y would be re-declared. This is no longer allowed starting from this release.

v0.11.19

06 May 04:12
Compare
Choose a tag to compare
  • Allow esbuild to be restarted in Deno (#1238)

    The esbuild API for Deno has an extra function called stop() that doesn't exist in esbuild's API for node. This is because Deno doesn't provide a way to stop esbuild automatically, so calling stop() is required to allow Deno to exit. However, once stopped the esbuild API could not be restarted.

    With this release, you can now continue to use esbuild after calling stop(). This will restart esbuild's API and means that you will need to call stop() again for Deno to be able to exit. This feature was contributed by @lucacasonato.

  • Fix code splitting edge case (#1252)

    This release fixes an edge case where bundling with code splitting enabled generated incorrect code if multiple ESM entry points re-exported the same re-exported symbol from a CommonJS file. In this case the cross-chunk symbol dependency should be the variable that holds the return value from the require() call instead of the original ESM named import clause item. When this bug occurred, the generated ESM code contained an export and import for a symbol that didn't exist, which caused a module initialization error. This case should now work correctly.

  • Fix code generation with declare class fields (#1242)

    This fixes a bug with TypeScript code that uses declare on a class field and your tsconfig.json file has "useDefineForClassFields": true. Fields marked as declare should not be defined in the generated code, but they were incorrectly being declared as undefined. These fields are now correctly omitted from the generated code.

  • Annotate module wrapper functions in debug builds (#1236)

    Sometimes esbuild needs to wrap certain modules in a function when bundling. This is done both for lazy evaluation and for CommonJS modules that use a top-level return statement. Previously these functions were all anonymous, so stack traces for errors thrown during initialization looked like this:

    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
        at getElectronPath (out.js:16:13)
        at out.js:19:21
        at out.js:1:45
        at out.js:24:3
        at out.js:1:45
        at out.js:29:3
        at out.js:1:45
        at Object.<anonymous> (out.js:33:1)
    

    This release adds names to these anonymous functions when minification is disabled. The above stack trace now looks like this:

    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
        at getElectronPath (out.js:19:15)
        at node_modules/electron/index.js (out.js:22:23)
        at __require (out.js:2:44)
        at src/base/window.js (out.js:29:5)
        at __require (out.js:2:44)
        at src/base/kiosk.js (out.js:36:5)
        at __require (out.js:2:44)
        at Object.<anonymous> (out.js:41:1)
    

    This is similar to Webpack's development-mode behavior:

    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
        at getElectronPath (out.js:23:11)
        at Object../node_modules/electron/index.js (out.js:27:18)
        at __webpack_require__ (out.js:96:41)
        at Object../src/base/window.js (out.js:49:1)
        at __webpack_require__ (out.js:96:41)
        at Object../src/base/kiosk.js (out.js:38:1)
        at __webpack_require__ (out.js:96:41)
        at out.js:109:1
        at out.js:111:3
        at Object.<anonymous> (out.js:113:12)
    

    These descriptive function names will additionally be available when using a profiler such as the one included in the "Performance" tab in Chrome Developer Tools. Previously all functions were named (anonymous) which made it difficult to investigate performance issues during bundle initialization.

  • Add CSS minification for more cases

    The following CSS minification cases are now supported:

    • The CSS margin property family is now minified including combining the margin-top, margin-right, margin-bottom, and margin-left properties into a single margin property.

    • The CSS padding property family is now minified including combining the padding-top, padding-right, padding-bottom, and padding-left properties into a single padding property.

    • The CSS border-radius property family is now minified including combining the border-top-left-radius, border-top-right-radius, border-bottom-right-radius, and border-bottom-left-radius properties into a single border-radius property.

    • The four special pseudo-elements ::before, ::after, ::first-line, and ::first-letter are allowed to be parsed with one : for legacy reasons, so the :: is now converted to : for these pseudo-elements.

    • Duplicate CSS rules are now deduplicated. Only the last rule is kept, since that's the only one that has any effect. This applies for both top-level rules and nested rules.

  • Preserve quotes around properties when minification is disabled (#1251)

    Previously the parser did not distinguish between unquoted and quoted properties, since there is no semantic difference. However, some tools such as Google Closure Compiler with "advanced mode" enabled attach their own semantic meaning to quoted properties, and processing code intended for Google Closure Compiler's advanced mode with esbuild was changing those semantics. The distinction between unquoted and quoted properties is now made in the following cases:

    import * as ns from 'external-pkg'
    console.log([
      { x: 1, 'y': 2 },
      { x() {}, 'y'() {} },
      class { x = 1; 'y' = 2 },
      class { x() {}; 'y'() {} },
      { x: x, 'y': y } = z,
      [x.x, y['y']],
      [ns.x, ns['y']],
    ])

    The parser will now preserve the quoted properties in these cases as long as --minify-syntax is not enabled. This does not mean that esbuild is officially supporting Google Closure Compiler's advanced mode, just that quoted properties are now preserved when the AST is pretty-printed. Google Closure Compiler's advanced mode accepts a language that shares syntax with JavaScript but that deviates from JavaScript semantics and there could potentially be other situations where preprocessing code intended for Google Closure Compiler's advanced mode with esbuild first causes it to break. If that happens, that is not a bug with esbuild.

v0.11.18

02 May 22:34
Compare
Choose a tag to compare
  • Add support for OpenBSD on x86-64 (#1235)

    Someone has asked for OpenBSD to be supported on x86-64. It should now be supported starting with this release.

  • Fix an incorrect warning about top-level this

    This was introduced in the previous release, and happens when using a top-level async arrow function with a compilation target that doesn't support it. The reason is that doing this generates a shim that preserves the value of this. However, this warning message is confusing because there is not necessarily any this present in the source code. The warning message has been removed in this case. Now it should only show up if this is actually present in the source code.

v0.11.17

01 May 10:11
Compare
Choose a tag to compare
  • Fix building with a large stdin string with Deno (#1219)

    When I did the initial port of esbuild's node-based API to Deno, I didn't realize that Deno's write(bytes) function doesn't actually write the provided bytes. Instead it may only write some of those bytes and needs to be repeatedly called again until it writes everything. This meant that calling esbuild's Deno-based API could hang if the API request was large enough, which can happen in practice when using the stdin string feature. The write API is now called in a loop so these hangs in Deno should now be fixed.

  • Add a warning about replacing this with undefined in ESM code (#1225)

    There is existing JavaScript code that sometimes references top-level this as a way to access the global scope. However, top-level this is actually specified to be undefined inside of ECMAScript module code, which makes referencing top-level this inside ESM code useless. This issue can come up when the existing JavaScript code is adapted for ESM by adding import and/or export. All top-level references to this are replaced with undefined when bundling to make sure ECMAScript module behavior is emulated correctly regardless of the environment in which the resulting code is run.

    With this release, esbuild will now warn about this when bundling:

     > example.mjs:1:61: warning: Top-level "this" will be replaced with undefined since this file is an ECMAScript module
        1 │ export let Array = (typeof window !== 'undefined' ? window : this).Array
          ╵                                                              ~~~~
       example.mjs:1:0: note: This file is considered an ECMAScript module because of the "export" keyword here
        1 │ export let Array = (typeof window !== 'undefined' ? window : this).Array
          ╵ ~~~~~~
    

    This warning is not unique to esbuild. Rollup also already has a similar warning:

    (!) `this` has been rewritten to `undefined`
    https://rollupjs.org/guide/en/#error-this-is-undefined
    example.mjs
    1: export let Array = (typeof window !== 'undefined' ? window : this).Array
                                                                    ^
    
  • Allow a string literal as a JSX fragment (#1217)

    TypeScript's JSX implementation allows you to configure a custom JSX factory and a custom JSX fragment, but requires that they are both valid JavaScript identifier member expression chains. Since esbuild's JSX implementation is based on TypeScript, esbuild has the same requirement. So React.createElement is a valid JSX factory value but ['React', 'createElement'] is not.

    However, the Mithril framework has decided to use "[" as a JSX fragment, which is not a valid JavaScript identifier member expression chain. This meant that using Mithril with esbuild required a workaround. In this release, esbuild now lets you use a string literal as a custom JSX fragment. It should now be easier to use esbuild's JSX implementation with libraries such as Mithril.

  • Fix metafile in onEnd with watch mode enabled (#1186)

    This release fixes a bug where the metafile property was incorrectly undefined inside plugin onEnd callbacks if watch mode is enabled for all builds after the first build. The metafile property was accidentally being set after calling onEnd instead of before.

v0.11.16

28 Apr 08:54
Compare
Choose a tag to compare
  • Fix TypeScript enum edge case (#1198)

    In TypeScript, you can reference the inner closure variable in an enum within the inner closure by name:

    enum A { B = A }

    The TypeScript compiler generates the following code for this case:

    var A;
    (function (A) {
      A[A["B"] = A] = "B";
    })(A || (A = {}));

    However, TypeScript also lets you declare an enum value with the same name as the inner closure variable. In that case, the value "shadows" the declaration of the inner closure variable:

    enum A { A = 1, B = A }

    The TypeScript compiler generates the following code for this case:

    var A;
    (function (A) {
      A[A["A"] = 1] = "A";
      A[A["B"] = 1] = "B";
    })(A || (A = {}));

    Previously esbuild reported a duplicate variable declaration error in the second case due to the collision between the enum value and the inner closure variable with the same name. With this release, the shadowing is now handled correctly.

  • Parse the @-moz-document CSS rule (#1203)

    This feature has been removed from the web because it's actively harmful, at least according to this discussion. However, there is one exception where @-moz-document url-prefix() { is accepted by Firefox to basically be an "if Firefox" conditional rule. Because of this, esbuild now parses the @-moz-document CSS rule. This should result in better pretty-printing and minification and no more warning when this rule is used.

  • Fix syntax error in TypeScript-specific speculative arrow function parsing (#1211)

    Because of grammar ambiguities, expressions that start with a parenthesis are parsed using what's called a "cover grammar" that is a super-position of both a parenthesized expression and an arrow function parameter list. In JavaScript, the cover grammar is unambiguously an arrow function if and only if the following token is a => token.

    But in TypeScript, the expression is still ambiguously a parenthesized expression or an arrow function if the following token is a : since it may be the second half of the ?: operator or a return type annotation. This requires speculatively attempting to reduce the cover grammar to an arrow function parameter list.

    However, when doing this esbuild eagerly reported an error if a default argument was encountered and the target is es5 (esbuild doesn't support lowering default arguments to ES5). This is problematic in the following TypeScript code since the parenthesized code turns out to not be an arrow function parameter list:

    function foo(check, hover) {
      return check ? (hover = 2, bar) : baz();
    }

    Previously this code incorrectly generated an error since hover = 2 was incorrectly eagerly validated as a default argument. With this release, the reporting of the default argument error when targeting es5 is now done lazily and only when it's determined that the parenthesized code should actually be interpreted as an arrow function parameter list.

  • Further changes to the behavior of the browser field (#1209)

    This release includes some changes to how the browser field in package.json is interpreted to better match how Browserify, Webpack, Parcel, and Rollup behave. The interpretation of this map in esbuild is intended to be applied if and only if it's applied by any one of these bundlers. However, there were some cases where esbuild applied the mapping and none of the other bundlers did, which could lead to build failures. These cases have been added to my growing list of browser field test cases and esbuild's behavior should now be consistent with other bundlers again.

  • Avoid placing a super() call inside a return statement (#1208)

    When minification is enabled, an expression followed by a return statement (e.g. a(); return b) is merged into a single statement (e.g. return a(), b). This is done because it sometimes results in smaller code. If the return statement is the only statement in a block and the block is in a single-statement context, the block can be removed which saves a few characters.

    Previously esbuild applied this rule to calls to super() inside of constructors. Doing that broke esbuild's class lowering transform that tries to insert class field initializers after the super() call. This transform isn't robust and only scans the top-level statement list inside the constructor, so inserting the super() call inside of the return statement means class field initializers were inserted before the super() call instead of after. This could lead to run-time crashes due to initialization failure.

    With this release, top-level calls to super() will no longer be placed inside return statements (in addition to various other kinds of statements such as throw, which are now also handled). This should avoid class field initializers being inserted before the super() call.

  • Fix a bug with onEnd and watch mode (#1186)

    This release fixes a bug where onEnd plugin callbacks only worked with watch mode when an onRebuild watch mode callback was present. Now onEnd callbacks should fire even if there is no onRebuild callback.

  • Fix an edge case with minified export names and code splitting (#1201)

    The names of symbols imported from other chunks were previously not considered for renaming during minified name assignment. This could cause a syntax error due to a name collision when two symbols have the same original name. This was just an oversight and has been fixed, so symbols imported from other chunks should now be renamed when minification is enabled.

  • Provide a friendly error message when you forget async (#1216)

    If the parser hits a parse error inside a non-asynchronous function or arrow expression and the previous token is await, esbuild will now report a friendly error about a missing async keyword instead of reporting the parse error. This behavior matches other JavaScript parsers including TypeScript, Babel, and V8.

    The previous error looked like this:

     > test.ts:2:8: error: Expected ";" but found "f"
        2 │   await f();
          ╵         ^
    

    The error now looks like this:

     > example.js:2:2: error: "await" can only be used inside an "async" function
        2 │   await f();
          ╵   ~~~~~
       example.js:1:0: note: Consider adding the "async" keyword here
        1 │ function f() {
          │ ^
          ╵ async
    

v0.11.15

26 Apr 07:57
Compare
Choose a tag to compare
  • Provide options for how to handle legal comments (#919)

    A "legal comment" is considered to be any comment that contains @license or @preserve or that starts with //! or /*!. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code.

    However, some people want to remove the automatically-generated license information before they distribute their code. To facilitate this, esbuild now provides several options for how to handle legal comments (via --legal-comments= in the CLI and legalComments in the JS API):

    • none: Do not preserve any legal comments
    • inline: Preserve all statement-level legal comments
    • eof: Move all statement-level legal comments to the end of the file
    • linked: Move all statement-level legal comments to a .LEGAL.txt file and link to them with a comment
    • external: Move all statement-level legal comments to a .LEGAL.txt file but to not link to them

    The default behavior is eof when bundling and inline otherwise.

  • Add onStart and onEnd callbacks to the plugin API

    Plugins can now register callbacks to run when a build is started and ended:

    const result = await esbuild.build({
      ...
      incremental: true,
      plugins: [{
        name: 'example',
        setup(build) {
          build.onStart(() => console.log('build started'))
          build.onEnd(result => console.log('build ended', result))
        },
      }],
    })
    await result.rebuild()

    One benefit of onStart and onEnd is that they are run for all builds including rebuilds (relevant for incremental mode, watch mode, or serve mode), so they should be a good place to do work related to the build lifecycle.

    More details:

    • build.onStart()

      You should not use an onStart callback for initialization since it can be run multiple times. If you want to initialize something, just put your plugin initialization code directly inside the setup function instead.

      The onStart callback can be async and can return a promise. However, the build does not wait for the promise to be resolved before starting, so a slow onStart callback will not necessarily slow down the build. All onStart callbacks are also run concurrently, not consecutively. The returned promise is purely for error reporting, and matters when the onStart callback needs to do an asynchronous operation that may fail. If your plugin needs to wait for an asynchronous task in onStart to complete before any onResolve or onLoad callbacks are run, you will need to have your onResolve or onLoad callbacks block on that task from onStart.

      Note that onStart callbacks do not have the ability to mutate build.initialOptions. The initial options can only be modified within the setup function and are consumed once the setup function returns. All rebuilds use the same initial options so the initial options are never re-consumed, and modifications to build.initialOptions that are done within onStart are ignored.

    • build.onEnd()

      All onEnd callbacks are run in serial and each callback is given access to the final build result. It can modify the build result before returning and can delay the end of the build by returning a promise. If you want to be able to inspect the build graph, you should set build.initialOptions.metafile = true and the build graph will be returned as the metafile property on the build result object.

v0.11.14

24 Apr 10:57
Compare
Choose a tag to compare
  • Implement arbitrary module namespace identifiers

    This introduces new JavaScript syntax:

    import {'🍕' as food} from 'file'
    export {food as '🧀'}

    The proposal for this feature appears to not be going through the regular TC39 process. It is being done as a subtle direct pull request instead. It seems appropriate for esbuild to support this feature since it has been implemented in V8 and has now shipped in Chrome 90 and node 16.

    According to the proposal, this feature is intended to improve interop with non-JavaScript languages which use exports that aren't valid JavaScript identifiers such as Foo::~Foo. In particular, WebAssembly allows any valid UTF-8 string as to be used as an export alias.

    This feature was actually already partially possible in previous versions of JavaScript via the computed property syntax:

    import * as ns from './file.json'
    console.log(ns['🍕'])

    However, doing this is very un-ergonomic and exporting something as an arbitrary name is impossible outside of export * from. So this proposal is designed to fully fill out the possibility matrix and make arbitrary alias names a proper first-class feature.

  • Implement more accurate sideEffects behavior from Webpack (#1184)

    This release adds support for the implicit **/ prefix that must be added to paths in the sideEffects array in package.json if the path does not contain /. Another way of saying this is if package.json contains a sideEffects array with a string that doesn't contain a / then it should be treated as a file name instead of a path. Previously esbuild treated all strings in this array as paths, which does not match how Webpack behaves. The result of this meant that esbuild could consider files to have no side effects while Webpack would consider the same files to have side effects. This bug should now be fixed.

v0.11.13

23 Apr 02:52
Compare
Choose a tag to compare
  • Implement ergonomic brand checks for private fields

    This introduces new JavaScript syntax:

    class Foo {
      #field
      static isFoo(x) {
        return #foo in x // This is an "ergonomic brand check"
      }
    }
    assert(Foo.isFoo(new Foo))

    The TC39 proposal for this feature is currently at stage 3 but has already been shipped in Chrome 91 and has also landed in Firefox. It seems reasonably inevitable given that it's already shipping and that it's a very simple feature, so it seems appropriate to add this feature to esbuild.

  • Add the --allow-overwrite flag (#1152)

    This is a new flag that allows output files to overwrite input files. It's not enabled by default because doing so means overwriting your source code, which can lead to data loss if your code is not checked in. But supporting this makes certain workflows easier by avoiding the need for a temporary directory so doing this is now supported.

  • Minify property accesses on object literals (#1166)

    The code {a: {b: 1}}.a.b will now be minified to 1. This optimization is relatively complex and hard to do safely. Here are some tricky cases that are correctly handled:

    var obj = {a: 1}
    assert({a: 1, a: 2}.a === 2)
    assert({a: 1, [String.fromCharCode(97)]: 2}.a === 2)
    assert({__proto__: obj}.a === 1)
    assert({__proto__: null}.a === undefined)
    assert({__proto__: null}.__proto__ === undefined)
    assert({a: function() { return this.b }, b: 1}.a() === 1)
    assert(({a: 1}.a = 2) === 2)
    assert(++{a: 1}.a === 2)
    assert.throws(() => { new ({ a() {} }.a) })
  • Improve arrow function parsing edge cases

    There are now more situations where arrow expressions are not allowed. This improves esbuild's alignment with the JavaScript specification. Some examples of cases that were previously allowed but that are now no longer allowed:

    1 + x => {}
    console.log(x || async y => {})
    class Foo extends async () => {} {}

v0.11.12

17 Apr 11:22
Compare
Choose a tag to compare
  • Fix a bug where -0 and 0 were collapsed to the same value (#1159)

    Previously esbuild would collapse Object.is(x ? 0 : -0, -0) into Object.is((x, 0), -0) during minification, which is incorrect. The IEEE floating-point value -0 is a different bit pattern than 0 and while they both compare equal, the difference is detectable in a few scenarios such as when using Object.is(). The minification transformation now checks for -0 vs. 0 and no longer has this bug. This fix was contributed by @rtsao.

  • Match the TypeScript compiler's output in a strange edge case (#1158)

    With this release, esbuild's TypeScript-to-JavaScript transform will no longer omit the namespace in this case:

    namespace Something {
      export declare function Print(a: string): void
    }
    Something.Print = function(a) {}

    This was previously omitted because TypeScript omits empty namespaces, and the namespace was considered empty because the export declare function statement isn't "real":

    namespace Something {
      export declare function Print(a: string): void
      setTimeout(() => Print('test'))
    }
    Something.Print = function(a) {}

    The TypeScript compiler compiles the above code into the following:

    var Something;
    (function (Something) {
      setTimeout(() => Print('test'));
    })(Something || (Something = {}));
    Something.Print = function (a) { };

    Notice how Something.Print is never called, and what appears to be a reference to the Print symbol on the namespace Something is actually a reference to the global variable Print. I can only assume this is a bug in TypeScript, but it's important to replicate this behavior inside esbuild for TypeScript compatibility.

    The TypeScript-to-JavaScript transform in esbuild has been updated to match the TypeScript compiler's output in both of these cases.

  • Separate the debug log level into debug and verbose

    You can now use --log-level=debug to get some additional information that might indicate some problems with your build, but that has a high-enough false-positive rate that it isn't appropriate for warnings, which are on by default. Enabling the debug log level no longer generates a torrent of debug information like it did in the past; that behavior is now reserved for the verbose log level instead.

v0.11.11

15 Apr 02:11
Compare
Choose a tag to compare
  • Initial support for Deno (#936)

    You can now use esbuild in the Deno JavaScript environment via esbuild's official Deno package. Using it looks something like this:

    import * as esbuild from 'https://deno.land/x/[email protected]/mod.js'
    const ts = 'let hasProcess: boolean = typeof process != "null"'
    const result = await esbuild.transform(ts, { loader: 'ts', logLevel: 'warning' })
    console.log('result:', result)
    esbuild.stop()

    It has basically the same API as esbuild's npm package with one addition: you need to call stop() when you're done because unlike node, Deno doesn't provide the necessary APIs to allow Deno to exit while esbuild's internal child process is still running.

  • Remove warnings about non-bundled use of require and import (#1153, #1142, #1132, #1045, #812, #661, #574, #512, #495, #480, #453, #410, #80)

    Previously esbuild had warnings when bundling about uses of require and import that are not of the form require(<string literal>) or import(<string literal>). These warnings existed because the bundling process must be able to statically-analyze all dynamic imports to determine which files must be included. Here are some real-world examples of cases that esbuild doesn't statically analyze:

    • From mongoose:

      require('./driver').set(require(global.MONGOOSE_DRIVER_PATH));
    • From moment:

      aliasedRequire = require;
      aliasedRequire('./locale/' + name);
    • From logform:

      function exposeFormat(name) {
        Object.defineProperty(format, name, {
          get() { return require(`./${name}.js`); }
        });
      }
      exposeFormat('align');

    All of these dynamic imports will not be bundled (i.e. they will be left as-is) and will crash at run-time if they are evaluated. Some of these crashes are ok since the code paths may have error handling or the code paths may never be used. Other crashes are not ok because the crash will actually be hit.

    The warning from esbuild existed to let you know that esbuild is aware that it's generating a potentially broken bundle. If you discover that your bundle is broken, it's nice to have a warning from esbuild to point out where the problem is. And it was just a warning so the build process still finishes and successfully generates output files. If you didn't want to see the warning, it was easy to turn it off via --log-level=error.

    However, there have been quite a few complaints about this warning. Some people seem to not understand the difference between a warning and an error, and think the build has failed even though output files were generated. Other people do not want to see the warning but also do not want to enable --log-level=error.

    This release removes this warning for both require and import. Now when you try to bundle code with esbuild that contains dynamic imports not of the form require(<string literal>) or import(<string literal>), esbuild will just silently generate a potentially broken bundle. This may affect people coming from other bundlers that support certain forms of dynamic imports that are not compatible with esbuild such as the Webpack-specific dynamic import() with pattern matching.