Skip to content

chore(deps): update dependency esbuild to ^0.14.14 #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 27, 2022

Conversation

renovate[bot]
Copy link

@renovate renovate bot commented Dec 12, 2021

WhiteSource Renovate

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
esbuild ^0.14.2 -> ^0.14.14 age adoption passing confidence

Release Notes

evanw/esbuild

v0.14.14

Compare Source

  • Fix bug with filename hashes and the file loader (#​1957)

    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.

  • Prefer the import condition for entry points (#​1956)

    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.

    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.

    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.

  • Make parsing of invalid @keyframes rules more robust (#​1959)

    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:

    /* Original code */
    @​keyframes x { . }
    @​keyframes y { 1% { a: b; } }
    
    /* Old output (with --minify) */
    @​keyframes x{y{1% {a: b;}}}
    
    /* New output (with --minify) */
    @​keyframes x{.}@​keyframes y{1%{a:b}}

v0.14.13

Compare Source

  • Be more consistent about external paths (#​619)

    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.

    This is the updated logic:

    • 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).

    • 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.

  • Attempt to explain why esbuild can't run (#​1819)

    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:

    $ ./node_modules/.bin/esbuild
    ./node_modules/esbuild/bin/esbuild:106
              throw new Error(`
              ^
    
    Error:
    You installed esbuild on another platform than the one you're currently using.
    This won't work because esbuild is written with native code and needs to
    install a platform-specific binary executable.
    
    Specifically the "esbuild-linux-arm64" package is present but this platform
    needs the "esbuild-darwin-arm64" package instead. People often get into this
    situation by installing esbuild on Windows or macOS and copying "node_modules"
    into a Docker image that runs Linux, or by copying "node_modules" between
    Windows and WSL environments.
    
    If you are installing with npm, you can try not copying the "node_modules"
    directory when you copy the files over, and running "npm ci" or "npm install"
    on the destination platform after the copy. Or you could consider using yarn
    instead which has built-in support for installing a package on multiple
    platforms simultaneously.
    
    If you are installing with yarn, you can try listing both this platform and the
    other platform in your ".yarnrc.yml" file using the "supportedArchitectures"
    feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures
    Keep in mind that this means multiple copies of esbuild will be present.
    
    Another alternative is to use the "esbuild-wasm" package instead, which works
    the same way on all platforms. But it comes with a heavy performance cost and
    can sometimes be 10x slower than the "esbuild" package, so you may also not
    want to do that.
    
        at generateBinPath (./node_modules/esbuild/bin/esbuild:106:17)
        at Object.<anonymous> (./node_modules/esbuild/bin/esbuild:161:39)
        at Module._compile (node:internal/modules/cjs/loader:1101:14)
        at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
        at Module.load (node:internal/modules/cjs/loader:981:32)
        at Function.Module._load (node:internal/modules/cjs/loader:822:12)
        at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
        at node:internal/main/run_main_module:17:47
    

v0.14.12

Compare Source

  • Ignore invalid @import rules in CSS (#​1946)

    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.

  • Print invalid CSS differently (#​1947)

    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:

    /* Original code */
    .bad { @&#8203;import url("other") }
    .red { background: red; }
    
    /* Old output (with --minify) */
    .bad{@&#8203;import url(other) } .red{background: red;}}
    
    /* New output (with --minify) */
    .bad{@&#8203;import url(other);}.red{background:red}
  • Warn about CSS nesting syntax (#​1945)

    There's a proposed CSS syntax for nesting rules 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.

  • Warn about } and > inside JSX elements

    The } and > characters are invalid inside JSX elements according to the JSX specification because they commonly result from typos like these that are hard to catch in code reviews:

    function F() {
      return <div>></div>;
    }
    function G() {
      return <div>{1}}</div>;
    }

    The TypeScript compiler already treats this as an error, so esbuild now treats this as an error in TypeScript files too. That looks like this:

    ✘ [ERROR] The character ">" is not valid inside a JSX element
    
        example.tsx:2:14:
          2 │   return <div>></div>;
            │               ^
            ╵               {'>'}
    
      Did you mean to escape it as "{'>'}" instead?
    
    ✘ [ERROR] The character "}" is not valid inside a JSX element
    
        example.tsx:5:17:
          5 │   return <div>{1}}</div>;
            │                  ^
            ╵                  {'}'}
    
      Did you mean to escape it as "{'}'}" instead?
    

    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 but Babel 8 hasn't been released yet. If you see this warning, I recommend fixing the invalid JSX syntax because it will become an error in the future.

  • Warn about basic CSS property typos

    This release now generates a warning if you use a CSS property that is one character off from a known CSS property:

    ▲ [WARNING] "marign-left" is not a known CSS property
    
        example.css:2:2:
          2 │   marign-left: 12px;
            │   ~~~~~~~~~~~
            ╵   margin-left
    
      Did you mean "margin-left" instead?
    

v0.14.11

Compare Source

  • Fix a bug with enum inlining (#​1903)

    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.

  • Warn about module.exports.foo = ... in ESM (#​1907)

    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;

    ▲ [WARNING] The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
    
        example.ts:2:0:
          2 │ module.exports.b = 1
            ╵ ~~~~~~
    
      This file is considered to be an ECMAScript module because of the "export" keyword here:
    
        example.ts:1:0:
          1 │ export let a = 1
            ╵ ~~~~~~
    
  • Enable esbuild's CLI with Deno (#​1913)

    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:

    deno run --allow-all "https://deno.land/x/[email protected]/mod.js" --version
    

v0.14.10

Compare Source

  • Enable tree shaking of classes with lowered static fields (#​175)

    If the configured target environment doesn't support static class fields, they are converted into a call to esbuild's __publicField function instead. However, esbuild's tree-shaking pass treated this call as a side effect, which meant that all classes with static fields were ineligible for tree shaking. This release fixes the problem by explicitly ignoring calls to the __publicField function during tree shaking side-effect determination. Tree shaking is now enabled for these classes:

    // Original code
    class Foo { static foo = 'foo' }
    class Bar { static bar = 'bar' }
    new Bar()
    
    // Old output (with --tree-shaking=true --target=es6)
    class Foo {
    }
    __publicField(Foo, "foo", "foo");
    class Bar {
    }
    __publicField(Bar, "bar", "bar");
    new Bar();
    
    // New output (with --tree-shaking=true --target=es6)
    class Bar {
    }
    __publicField(Bar, "bar", "bar");
    new Bar();
  • Treat --define:foo=undefined as an undefined literal instead of an identifier (#​1407)

    References to the global variable undefined are automatically replaced with the literal value for undefined, which appears as void 0 when printed. This allows for additional optimizations such as collapsing undefined ?? bar into just bar. However, this substitution was not done for values specified via --define:. As a result, esbuild could potentially miss out on certain optimizations in these cases. With this release, it's now possible to use --define: to substitute something with an undefined literal:

    // Original code
    let win = typeof window !== 'undefined' ? window : {}
    
    // Old output (with --define:window=undefined --minify)
    let win=typeof undefined!="undefined"?undefined:{};
    
    // New output (with --define:window=undefined --minify)
    let win={};
  • Add the --drop:debugger flag (#​1809)

    Passing this flag causes all debugger; statements to be removed from the output. This is similar to the drop_debugger: true flag available in the popular UglifyJS and Terser JavaScript minifiers.

  • Add the --drop:console flag (#​28)

    Passing this flag causes all console.xyz() API calls to be removed from the output. This is similar to the drop_console: true flag available in the popular UglifyJS and Terser JavaScript minifiers.

    WARNING: Using this flag can introduce bugs into your code! This flag removes the entire call expression including all call arguments. If any of those arguments had important side effects, using this flag will change the behavior of your code. Be very careful when using this flag. If you want to remove console API calls without removing arguments with side effects (which does not introduce bugs), you should mark the relevant API calls as pure instead like this: --pure:console.log --minify.

  • Inline calls to certain no-op functions when minifying (#​290, #​907)

    This release makes esbuild inline two types of no-op functions: empty functions and identity functions. These most commonly arise when most of the function body is eliminated as dead code. In the examples below, this happens because we use --define:window.DEBUG=false to cause dead code elimination inside the function body of the resulting if (false) statement. This inlining is a small code size and performance win but, more importantly, it allows for people to use these features to add useful abstractions that improve the development experience without needing to worry about the run-time performance impact.

    An identity function is a function that just returns its argument. Here's an example of inlining an identity function:

    // Original code
    function logCalls(fn) {
      if (window.DEBUG) return function(...args) {
        console.log('calling', fn.name, 'with', args)
        return fn.apply(this, args)
      }
      return fn
    }
    export const foo = logCalls(function foo() {})
    
    // Old output (with --minify --define:window.DEBUG=false --tree-shaking=true)
    function o(n){return n}export const foo=o(function(){});
    
    // New output (with --minify --define:window.DEBUG=false --tree-shaking=true)
    export const foo=function(){};

    An empty function is a function with an empty body. Here's an example of inlining an empty function:

    // Original code
    function assertNotNull(val: Object | null): asserts val is Object {
      if (window.DEBUG && val === null) throw new Error('null assertion failed');
    }
    export const val = getFoo();
    assertNotNull(val);
    console.log(val.bar);
    
    // Old output (with --minify --define:window.DEBUG=false --tree-shaking=true)
    function l(o){}export const val=getFoo();l(val);console.log(val.bar);
    
    // New output (with --minify --define:window.DEBUG=false --tree-shaking=true)
    export const val=getFoo();console.log(val.bar);

    To get this behavior you'll need to use the function keyword to define your function since that causes the definition to be hoisted, which eliminates concerns around initialization order. These features also work across modules, so functions are still inlined even if the definition of the function is in a separate module from the call to the function. To get cross-module function inlining to work, you'll need to have bundling enabled and use the import and export keywords to access the function so that esbuild can see which functions are called. And all of this has been added without an observable impact to compile times.

    I previously wasn't able to add this to esbuild easily because of esbuild's low-pass compilation approach. The compiler only does three full passes over the data for speed. The passes are roughly for parsing, binding, and printing. It's only possible to inline something after binding but it needs to be inlined before printing. Also the way module linking was done made it difficult to roll back uses of symbols that were inlined, so the symbol definitions were not tree shaken even when they became unused due to inlining.

    The linking issue was somewhat resolved when I fixed #​128 in the previous release. To implement cross-module inlining of TypeScript enums, I came up with a hack to defer certain symbol uses until the linking phase, which happens after binding but before printing. Another hack is that inlining of TypeScript enums is done directly in the printer to avoid needing another pass.

    The possibility of these two hacks has unblocked these simple function inlining use cases that are now handled. This isn't a fully general approach because optimal inlining is recursive. Inlining something may open up further inlining opportunities, which either requires multiple iterations or a worklist algorithm, both of which don't work when doing late-stage inlining in the printer. But the function inlining that esbuild now implements is still useful even though it's one level deep, and so I believe it's still worth adding.

v0.14.9

Compare Source

  • Implement cross-module tree shaking of TypeScript enum values (#​128)

    If your bundle uses TypeScript enums across multiple files, esbuild is able to inline the enum values as long as you export and import the enum using the ES module export and import keywords. However, this previously still left the definition of the enum in the bundle even when it wasn't used anymore. This was because esbuild's tree shaking (i.e. dead code elimination) is based on information recorded during parsing, and at that point we don't know which imported symbols are inlined enum values and which aren't.

    With this release, esbuild will now remove enum definitions that become unused due to cross-module enum value inlining. Property accesses off of imported symbols are now tracked separately during parsing and then resolved during linking once all inlined enum values are known. This behavior change means esbuild's support for cross-module inlining of TypeScript enums is now finally complete. Here's an example:

    // entry.ts
    import { Foo } from './enum'
    console.log(Foo.Bar)
    
    // enum.ts
    export enum Foo { Bar }

    Bundling the example code above now results in the enum definition being completely removed from the bundle:

    // Old output (with --bundle --minify --format=esm)
    var r=(o=>(o[o.Bar=0]="Bar",o))(r||{});console.log(0);
    
    // New output (with --bundle --minify --format=esm)
    console.log(0);
  • Fix a regression with export {} from and CommonJS (#​1890)

    This release fixes a regression that was introduced by the change in 0.14.7 that avoids calling the __toESM wrapper for import statements that are converted to require calls and that don't use the default or __esModule export names. The previous change was correct for the import {} from syntax but not for the export {} from syntax, which meant that in certain cases with re-exported values, the value of the default import could be different than expected. This release fixes the regression.

  • Warn about using module or exports in ESM code (#​1887)

    CommonJS export variables cannot be referenced in ESM code. If you do this, they are treated as global variables instead. This release includes a warning for people that try to use both CommonJS and ES module export styles in the same file. Here's an example:

    export enum Something {
      a,
      b,
    }
    module.exports = { a: 1, b: 2 }

    Running esbuild on that code now generates a warning that looks like this:

    ▲ [WARNING] The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
    
        example.ts:5:0:
          5 │ module.exports = { a: 1, b: 2 }
            ╵ ~~~~~~
    
      This file is considered to be an ECMAScript module because of the "export" keyword here:
    
        example.ts:1:0:
          1 │ export enum Something {
            ╵ ~~~~~~
    

v0.14.8

Compare Source

  • Add a resolve API for plugins (#​641, #​1652)

    Plugins now have access to a new API called resolve that runs esbuild's path resolution logic and returns the result to the caller. This lets you write plugins that can reuse esbuild's complex built-in path resolution logic to change the inputs and/or adjust the outputs. Here's an example:

    let examplePlugin = {
      name: 'example',
      setup(build) {
        build.onResolve({ filter: /^example$/ }, async () => {
          const result = await build.resolve('./foo', { resolveDir: '/bar' })
          if (result.errors.length > 0) return result
          return { ...result, external: true }
        })
      },
    }

    This plugin intercepts imports to the path example, tells esbuild to resolve the import ./foo in the directory /bar, and then forces whatever path esbuild returns to be considered external. Here are some additional details:

    • If you don't pass the optional resolveDir parameter, esbuild will still run onResolve plugin callbacks but will not attempt any path resolution itself. All of esbuild's path resolution logic depends on the resolveDir parameter including looking for packages in node_modules directories (since it needs to know where those node_modules directories might be).

    • If you want to resolve a file name in a specific directory, make sure the input path starts with ./. Otherwise the input path will be treated as a package path instead of a relative path. This behavior is identical to esbuild's normal path resolution logic.

    • If path resolution fails, the errors property on the returned object will be a non-empty array containing the error information. This function does not always throw an error when it fails. You need to check for errors after calling it.

    • The behavior of this function depends on the build configuration. That's why it's a property of the build object instead of being a top-level API call. This also means you can't call it until all plugin setup functions have finished since these give plugins the opportunity to adjust the build configuration before it's frozen at the start of the build. So the new resolve function is going to be most useful inside your onResolve and/or onLoad callbacks.

    • There is currently no attempt made to detect infinite path resolution loops. Calling resolve from within onResolve with the same parameters is almost certainly a bad idea.

  • Avoid the CJS-to-ESM wrapper in some cases (#​1831)

    Import statements are converted into require() calls when the output format is set to CommonJS. To convert from CommonJS semantics to ES module semantics, esbuild wraps the return value in a call to esbuild's __toESM() helper function. However, the conversion is only needed if it's possible that the exports named default or __esModule could be accessed.

    This release avoids calling this helper function in cases where esbuild knows it's impossible for the default or __esModule exports to be accessed, which results in smaller and faster code. To get this behavior, you have to use the import {} from import syntax:

    // Original code
    import { readFile } from "fs";
    readFile();
    
    // Old output (with --format=cjs)
    var __toESM = (module, isNodeMode) => {
      ...
    };
    var import_fs = __toESM(require("fs"));
    (0, import_fs.readFile)();
    
    // New output (with --format=cjs)
    var import_fs = require("fs");
    (0, import_fs.readFile)();
  • Strip overwritten function declarations when minifying (#​610)

    JavaScript allows functions to be re-declared, with each declaration overwriting the previous declaration. This type of code can sometimes be emitted by automatic code generators. With this release, esbuild now takes this behavior into account when minifying to drop all but the last declaration for a given function:

    // Original code
    function foo() { console.log(1) }
    function foo() { console.log(2) }
    
    // Old output (with --minify)
    function foo(){console.log(1)}function foo(){console.log(2)}
    
    // New output (with --minify)
    function foo(){console.log(2)}
  • Add support for the Linux IBM Z 64-bit Big Endian platform (#​1864)

    With this release, the esbuild package now includes a Linux binary executable for the IBM System/390 64-bit architecture. This new platform was contributed by @​shahidhs-ibm.

  • Allow whitespace around : in JSX elements (#​1877)

    This release allows you to write the JSX <rdf:Description rdf:ID="foo" /> as <rdf : Description rdf : ID="foo" /> instead. Doing this is not forbidden by the JSX specification. While this doesn't work in TypeScript, it does work with other JSX parsers in the ecosystem, so support for this has been added to esbuild.

v0.14.7

Compare Source

  • Cross-module inlining of TypeScript enum constants (#​128)

    This release adds inlining of TypeScript enum constants across separate modules. It activates when bundling is enabled and when the enum is exported via the export keyword and imported via the import keyword:

    // foo.ts
    export enum Foo { Bar }
    
    // bar.ts
    import { Foo } from './foo.ts'
    console.log(Foo.Bar)

    The access to Foo.Bar will now be compiled into 0 /* Bar */ even though the enum is defined in a separate file. This inlining was added without adding another pass (which would have introduced a speed penalty) by splitting the code for the inlining between the existing parsing and printing passes. Enum inlining is active whether or not you use enum or const enum because it improves performance.

    To demonstrate the performance improvement, I compared the performance of the TypeScript compiler built by bundling the TypeScript compiler source code with esbuild before and after this change. The speed of the compiler was measured by using it to type check a small TypeScript code base. Here are the results:

    tsc with esbuild 0.14.6 with esbuild 0.14.7
    Time 2.96s 3.45s 2.95s

    As you can see, enum inlining gives around a 15% speedup, which puts the esbuild-bundled version at the same speed as the offical TypeScript compiler build (the tsc column)!

    The specifics of the benchmark aren't important here since it's just a demonstration of how enum inlining can affect performance. But if you're wondering, I type checked the Rollup code base using a work-in-progress branch of the TypeScript compiler that's part of the ongoing effort to convert their use of namespaces into ES modules.

  • Mark node built-in modules as having no side effects (#​705)

    This release marks node built-in modules such as fs as being side-effect free. That means unused imports to these modules are now removed when bundling, which sometimes results in slightly smaller code. For example:

    // Original code
    import fs from 'fs';
    import path from 'path';
    console.log(path.delimiter);
    
    // Old output (with --bundle --minify --platform=node --format=esm)
    import"fs";import o from"path";console.log(o.delimiter);
    
    // New output (with --bundle --minify --platform=node --format=esm)
    import o from"path";console.log(o.delimiter);

    Note that these modules are only automatically considered side-effect when bundling for node, since they are only known to be side-effect free imports in that environment. However, you can customize this behavior with a plugin by returning external: true and sideEffects: false in an onResolve callback for whatever paths you want to be treated this way.

  • Recover from a stray top-level } in CSS (#​1876)

    This release fixes a bug where a stray } at the top-level of a CSS file would incorrectly truncate the remainder of the file in the output (although not without a warning). With this release, the remainder of the file is now still parsed and printed:

    /* Original code */
    .red {
      color: red;
    }
    }
    .blue {
      color: blue;
    }
    .green {
      color: green;
    }
    
    /* Old output (with --minify) */
    .red{color:red}
    
    /* New output (with --minify) */
    .red{color:red}} .blue{color:#&#8203;00f}.green{color:green}

    This fix was contributed by @​sbfaulkner.

v0.14.6

Compare Source

  • Fix a minifier bug with BigInt literals

    Previously expression simplification optimizations in the minifier incorrectly assumed that numeric operators always return numbers. This used to be true but has no longer been true since the introduction of BigInt literals in ES2020. Now numeric operators can return either a number or a BigInt depending on the arguments. This oversight could potentially have resulted in behavior changes. For example, this code printed false before being minified and true after being minified because esbuild shortened === to == under the false assumption that both operands were numbers:

    var x = 0;
    console.log((x ? 2 : -1n) === -1);

    The type checking logic has been rewritten to take into account BigInt literals in this release, so this incorrect simplification is no longer applied.

  • Enable removal of certain unused template literals (#​1853)

    This release contains improvements to the minification of unused template literals containing primitive values:

    // Original code
    `${1}${2}${3}`;
    `${x ? 1 : 2}${y}`;
    
    // Old output (with --minify)
    ""+1+2+3,""+(x?1:2)+y;
    
    // New output (with --minify)
    x,`${y}`;

    This can arise when the template literals are nested inside of another function call that was determined to be unnecessary such as an unused call to a function marked with the /* @&#8203;__PURE__ */ pragma.

    This release also fixes a bug with this transformation where minifying the unused expression `foo ${bar}` into "" + bar changed the meaning of the expression. Template string interpolation always calls toString while string addition may call valueOf instead. This unused expression is now minified to `${bar}`, which is slightly longer but which avoids the behavior change.

  • Allow keyof/readonly/infer in TypeScript index signatures (#​1859)

    This release fixes a bug that prevented these keywords from being used as names in index signatures. The following TypeScript code was previously rejected, but is now accepted:

    interface Foo {
      [keyof: string]: number
    }

    This fix was contributed by @​magic-akari.

  • Avoid warning about import.meta if it's replaced (#​1868)

    It's possible to replace the import.meta expression using the --define: feature. Previously doing that still warned that the import.meta syntax was not supported when targeting ES5. With this release, there will no longer be a warning in this case.

v0.14.5

Compare Source

  • Fix an issue with the publishing script

    This release fixes a missing dependency issue in the publishing script where it was previously possible for the published binary executable to have an incorrect version number.

v0.14.4

Compare Source

  • Adjust esbuild's handling of default exports and the __esModule marker (#​532, #​1591, #​1719)

    This change requires some background for context. Here's the history to the best of my understanding:

    When the ECMAScript module import/export syntax was being developed, the CommonJS module format (used in Node.js) was already widely in use. Because of this the export name called default was given special a syntax. Instead of writing import { default as foo } from 'bar' you can just write import foo from 'bar'. The idea was that when ECMAScript modules (a.k.a. ES modules) were introduced, you could import existing CommonJS modules using the new import syntax for compatibility. Since CommonJS module exports are dynamic while ES module exports are static, it's not generally possible to determine a CommonJS module's export names at module instantiation time since the code hasn't been evaluated yet. So the value of module.exports is just exported as the default export and the special default import syntax gives you easy access to module.exports (i.e. const foo = require('bar') is the same as import foo from 'bar').

    However, it took a while for ES module syntax to be supported natively by JavaScript runtimes, and people still wanted to start using ES module syntax in the meantime. The Babel JavaScript compiler let you do this. You could transform each ES module file into a CommonJS module file that behaved the same. However, this transformation has a problem: emulating the import syntax accurately as described above means that export default 0 and import foo from 'bar' will no longer line up when transformed to CommonJS. The code export default 0 turns into module.exports.default = 0 and the code import foo from 'bar' turns into const foo = require('bar'), meaning foo is 0 before the transformation but foo is { default: 0 } after the transformation.

    To fix this, Babel sets the property __esModule to true as a signal to itself when it converts an ES module to a CommonJS module. Then, when importing a default export, it can know to use the value of module.exports.default instead of module.exports to make sure the behavior of the CommonJS modules correctly matches the behavior of the original ES modules. This fix has been widely adopted across the ecosystem and has made it into other tools such as TypeScript and even esbuild.

    However, when Node.js finally released their ES module implementation, they went with the original implementation where the default export is always module.exports, which broke compatibility with the existing ecosystem of ES modules that had been cross-compiled into CommonJS modules by Babel. You now have to either add or remove an additional .default property depending on whether your code needs to run in a Node environment or in a Babel environment, which created an interoperability headache. In addition, JavaScript tools such as esbuild now need to guess whether you want Node-style or Babel-style default imports. There's no way for a tool to know with certainty which one a given file is expecting and if your tool guesses wrong, your code will break.

    This release changes esbuild's heuristics around default exports and the __esModule marker to attempt to improve compatibility with Webpack and Node, which is what most packages are tuned for. The behavior changes are as follows:

    Old behavior:

    • If an import statement is used to load a CommonJS file and a) module.exports is an object, b) module.exports.__esModule is truthy, and c) the property default exists in module.exports, then esbuild would set the default export to module.exports.default (like Babel). Otherwise the default export was set to module.exports (like Node).

    • If a require call is used to load an ES module file, the returned module namespace object had the __esModule property set to true. This behaved as if the ES module had been converted to CommonJS via a Babel-compatible transformation.

    • The __esModule marker could inconsistently appear on module namespace objects (i.e. import * as) when writing pure ESM code. Specifically, if a module namespace object was materialized then the __esModule marker was present, but if it was optimized away then the __esModule marker was absent.

    • It was not allowed to create an ES module export named __esModule. This avoided generating code that might break due to the inconsistency mentioned above, and also avoided issues with duplicate definitions of __esModule.

    New behavior:

    • If an import statement is used to load a CommonJS file and a) module.exports is an object, b) module.exports.__esModule is truthy, and c) the file name does not end in either .mjs or .mts and the package.json file does not contain "type": "module", then esbuild will set the default export to module.exports.default (like Babel). Otherwise the default export is set to module.exports (like Node).

      Note that this means the default export may now be undefined in situations where it previously wasn't undefined. This matches Webpack's behavior so it should hopefully be more compatible.

      Also note that this means import behavior now depends on the file extension and on the contents of package.json. This also matches Webpack's behavior to hopefully improve compatibility.

    • If a require call is used to load an ES module file, the returned module namespace object has the __esModule property set to true. This behaves as if the ES module had been converted to CommonJS via a Babel-compatible transformation.

    • If an import statement or import() expression is used to load an ES module, the __esModule marker should now never be present on the module namespace object. This frees up the __esModule export name for use with ES modules.

    • It's now allowed to use __esModule as a normal export name in an ES module. This property will be accessible to other ES modules but will not be accessible to code that loads the ES module using require, where they will observe the property set to true instead.

v0.14.3

Compare Source

  • Pass the current esbuild instance to JS plugins (#​1790)

    Previously JS plugins that wanted to run esbuild had to require('esbuild') to get the esbuild object. However, that could potentially result in a different version of esbuild. This is also more complicated to do outside of node (such as within a browser). With this release, the current esbuild instance is now passed to JS plugins as the esbuild property:

    let examplePlugin = {
      name: 'example',
      setup(build) {
        console.log(build.esbuild.version)
        console.log(build.esbuild.transformSync('1+2'))
      },
    }
  • Disable calc() transform for results with non-finite numbers (#​1839)

    This release disables minification of calc() expressions when the result contains NaN, -Infinity, or Infinity. These numbers are valid inside of calc() expressions but not outside of them, so the calc() expression must be preserved in these cases.

  • Move "use strict" before injected shim imports (#​1837)

    If a CommonJS file contains a "use strict" directive, it could potentially be unintentionally disabled by esbuild when using the "inject" feature when bundling is enabled. This is because the inject feature was inserting a call to the initializer for the injected file before the "use strict" directive. In JavaScript, directives do not apply if they come after a non-directive statement. This release fixes the problem by moving the "use strict" directive before the initializer for the injected file so it isn't accidentally disabled.

  • Pass the ignored path query/hash suffix to onLoad plugins (#​1827)

    The built-in onResolve handler that comes with esbuild can strip the query/hash suffix off of a path during path resolution. For example, url("fonts/icons.eot?#iefix") can be resolved to the file fonts/icons.eot. For context, IE8 has a bug where it considers the font face URL to extend to the last ) instead of the first ). In the example below, IE8 thinks the URL for the font is Example.eot?#iefix') format('eot'), url('Example.ttf') format('truetype so by adding ?#iefix, IE8 thinks the URL has a path of Example.eot and a query string of ?#iefix') format('eot... and can load the font file:

    @&#8203;font-face {
      font-family: 'Example';
      src: url('Example.eot?#iefix') format('eot'), url('Example.ttf') format('truetype');
    }

    However, the suffix is not currently passed to esbuild and plugins may want to use this suffix for something. Previously plugins had to add their own onResolve handler if they wanted to use the query suffix. With this release, the suffix can now be returned by plugins from onResolve and is now passed to plugins in onLoad:

    let examplePlugin = {
      name: 'example',
      setup(build) {
        build.onResolve({ filter: /.*/ }, args => {
          return { path: args.path, suffix: '?#iefix' }
        })
    
        build.onLoad({ filter: /.*/ }, args => {
          console.log({ path: args.path, suffix: args.suffix })
        })
      },
    }

    The suffix is deliberately not included in the path that's provided to plugins because most plugins won't know to handle this strange edge case and would likely break. Keeping the suffix out of the path means that plugins can opt-in to handling this edge case if they want to, and plugins that aren't aware of this edge case will likely still do something reasonable.


Configuration

📅 Schedule: At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, click this checkbox.

This PR has been generated by WhiteSource Renovate. View repository job log here.

@vercel
Copy link

vercel bot commented Dec 12, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/yurtaev-egor/yurtaev-github-io/BbwxxuHzELvmSwF32DAov4dnDWDP
✅ Preview: https://yurtaev-github-io-git-renovate-esbuild-0x-yurtaev-egor.vercel.app

@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from abdc769 to d9012f7 Compare December 14, 2021 19:05
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.3 chore(deps): update dependency esbuild to ^0.14.5 Dec 14, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from d9012f7 to 6e618c7 Compare December 19, 2021 13:01
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from 6e618c7 to 4f128f8 Compare December 20, 2021 08:29
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.5 chore(deps): update dependency esbuild to ^0.14.6 Dec 20, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from 4f128f8 to be6b04a Compare December 21, 2021 20:35
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.6 chore(deps): update dependency esbuild to ^0.14.7 Dec 21, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from be6b04a to a28f75f Compare December 23, 2021 05:40
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.7 chore(deps): update dependency esbuild to ^0.14.8 Dec 23, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from a28f75f to 56758c0 Compare December 29, 2021 00:57
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.8 chore(deps): update dependency esbuild to ^0.14.9 Dec 29, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from 56758c0 to dca7ffb Compare December 31, 2021 17:18
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.9 chore(deps): update dependency esbuild to ^0.14.10 Dec 31, 2021
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from dca7ffb to c92d875 Compare January 9, 2022 00:47
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.10 chore(deps): update dependency esbuild to ^0.14.11 Jan 9, 2022
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from c92d875 to 43e71cc Compare January 21, 2022 00:44
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.11 chore(deps): update dependency esbuild to ^0.14.12 Jan 21, 2022
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from 43e71cc to df1cfe8 Compare January 22, 2022 17:49
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.12 chore(deps): update dependency esbuild to ^0.14.13 Jan 22, 2022
@renovate renovate bot force-pushed the renovate/esbuild-0.x branch from 22ab7cf to e81a151 Compare January 26, 2022 01:08
@renovate renovate bot changed the title chore(deps): update dependency esbuild to ^0.14.13 chore(deps): update dependency esbuild to ^0.14.14 Jan 26, 2022
@yurtaev yurtaev merged commit 38a6a96 into master Jan 27, 2022
@renovate renovate bot deleted the renovate/esbuild-0.x branch January 27, 2022 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants