Skip to content

v0.12.2

Compare
Choose a tag to compare
@github-actions github-actions released this 25 May 09:59
  • Fix various code generation and minification issues (#1305)

    This release fixes the following issues, which were all identified by running esbuild against the latest UglifyJS test suite:

    • The in operator is now surrounded parentheses inside arrow function expression bodies inside for loop initializers:

      // Original code
      for ((x => y in z); 0; ) ;
      
      // Old output
      for ((x) => y in z; 0; ) ;
      
      // New output
      for ((x) => (y in z); 0; ) ;

      Without this, the in operator would cause the for loop to be considered a for-in loop instead.

    • The statement return undefined; is no longer minified to return; inside async generator functions:

      // Original code
      return undefined;
      
      // Old output
      return;
      
      // New output
      return void 0;

      Using return undefined; inside an async generator function has the same effect as return await undefined; which schedules a task in the event loop and runs code in a different order than just return;, which doesn't hide an implicit await expression.

    • Property access expressions are no longer inlined in template tag position:

      // Original code
      (null, a.b)``, (null, a[b])``;
      
      // Old output
      a.b``, a[b]``;
      
      // New output
      (0, a.b)``, (0, a[b])``;

      The expression a.b`c` is different than the expression (0, a.b)`c`. The first calls the function a.b with a as the value for this but the second calls the function a.b with the default value for this (the global object in non-strict mode or undefined in strict mode).

    • Verbatim __proto__ properties inside object spread are no longer inlined when minifying:

      // Original code
      x = { ...{ __proto__: { y: true } } }.y;
      
      // Old output
      x = { __proto__: { y: !0 } }.y;
      
      // New output
      x = { ...{ __proto__: { y: !0 } } }.y;

      A verbatim (i.e. non-computed non-method) property called __proto__ inside an object literal actually sets the prototype of the surrounding object literal. It does not add an "own property" called __proto__ to that object literal, so inlining it into the parent object literal would be incorrect. The presence of a __proto__ property now stops esbuild from applying the object spread inlining optimization when minifying.

    • The value of this has now been fixed for lowered private class members that are used as template tags:

      // Original code
      x = (new (class {
        a = this.#c``;
        b = 1;
        #c() { return this }
      })).a.b;
      
      // Old output
      var _c, c_fn, _a;
      x = new (_a = class {
        constructor() {
          __privateAdd(this, _c);
          __publicField(this, "a", __privateMethod(this, _c, c_fn)``);
          __publicField(this, "b", 1);
        }
      }, _c = new WeakSet(), c_fn = function() {
        return this;
      }, _a)().a.b;
      
      // New output
      var _c, c_fn, _a;
      x = new (_a = class {
        constructor() {
          __privateAdd(this, _c);
          __publicField(this, "a", __privateMethod(this, _c, c_fn).bind(this)``);
          __publicField(this, "b", 1);
        }
      }, _c = new WeakSet(), c_fn = function() {
        return this;
      }, _a)().a.b;

      The value of this here should be an instance of the class because the template tag is a property access expression. However, it was previously the default value (the global object in non-strict mode or undefined in strict mode) instead due to the private member transformation, which is incorrect.

    • Invalid escape sequences are now allowed in tagged template literals

      This implements the template literal revision feature: https://github.com/tc39/proposal-template-literal-revision. It allows you to process tagged template literals using custom semantics that don't follow JavaScript escape sequence rules without causing a syntax error:

      console.log((x => x.raw)`invalid \unicode escape sequence`)