swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
31.21k stars 1.23k forks source link

SWC Compress producing invalid await inside of sync callback #6837

Closed christiango closed 1 year ago

christiango commented 1 year ago

Describe the bug

We started playing with swc minify for webpack and noticed one of our chunks produced invalid output that the browser failed to parse. I spent some time to get a minimal repro of the issue here.

Input code

class Class1 {}

function isClass2(node) {
  return node instanceof Class2;
}

Class1.isClass2 = isClass2;
export class Class2 extends Class1 {
  constructor() {
    super();
    this.method1 = async () => {
      let var1;
      const function1 = () => {};

      var1 = await Class2.method2();
      await function1()
        .then(() => {
          console.log(var1);
        })
        .catch();
    };
  }

  static async method2() {}
}

Config

{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": false
    },
    "target": "es2020",
    "loose": false,
    "minify": {
      "compress": {
        "arguments": false,
        "arrows": true,
        "booleans": true,
        "booleans_as_integers": false,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": false,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true
      },
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}

Playground link

https://play.swc.rs/?version=1.3.27&code=H4sIAAAAAAAAA12Ry27DIBBF95b8D3dJNpbsrZVu%2BiUIT2IkFyIYt6ki%2Fr1gHo66wWKYOedi1Ca9x2daR7xC3%2FXdbTeKtTXQ%2FqhPwtiFLnj1HeCId2eQKtDGszSK7C0DprnvDkLGDXUe14aKHfR8WMdQp3gCPZnMcuZIJmUj3u2KrRNFDvj9QXE75x2v2g9fxKtdxiiR%2FtcoxObrR%2B0HNmJ8SzfOtXBwUS%2BZ5spEmFP23JQmEvFHai4hi2hqdpTjhhKXegAMvJIR%2F7JUvd1o2OxdJMtJA8I7QElWa5OF4xtywvjbWaty3xbreL7wB8xZVRDRAQAA&config=H4sIAAAAAAAAA22TQZLjIAxF7%2BJ1Fl29mEUfYHZ9BkoB4ZDByIVEOq5U7t7CsXGczM56%2FhLiS9y6M9vu69aNkBlz%2FeIpCVy7rw7tAGxzGKU7qEyRh8h4P3QCuUepEv78%2BPzQ35GIcREcuiGk4KdazNIwZmSu35pUBkzCTQc504%2BGkotGR6KIkN5iA2xCEuwxb6mWYoSR0Vwgt4x6GuTAlHaoCDozZhqfaHJBAiUttjKH4Iwlhw2EjFbCBTeJ1lBJYm2sdTJDh8fS99XAhxIvEAtIq4XX2QY9seWdKLAYXxK%2FoF2nD%2FS45KIK3mSUktOqOVNIOx%2F%2BIWqfEZgTDLhlztzrHPZK%2Fx9VSF6HKFOjOuGtq4S9Xs6E4NsNa9eYJWxuZXTFYr2h3YovcHchDg4Neq9ut2T%2BCWJPWzGZRiTfQnUN%2FDaDR2jWfdrTugJv8K92Jc%2FjWPgAcnplPA1Him8lBpQTuTesRgi9wqzbex1faUkO1WZ0Tz8K17CtqQ5fyMT62lafdSE0x%2FSRjm199VEOkPq2lvcKyJUKbrN582v9092317muE38vwrnQL9TiLpcSBAAA

Expected behavior

The code generated is equivalent and parses correctly in the browser

Actual behavior

The generated code is below

class Class1 {
}
Class1.isClass2 = function(node) {
    return node instanceof Class2;
};
export class Class2 extends Class1 {
    static async method2() {}
    constructor(){
        super(), this.method1 = async ()=>{
            await (void 0).then(()=>{
                console.log(await Class2.method2());
            }).catch();
        };
    }
}

There is an await inside the console.log that is not inside an async function inside the then block.

Version

1.3.27

Additional context

No response

christiango commented 1 year ago

There seems to be an even simpler repro here:

https://play.swc.rs/?version=1.3.27&code=H4sIAAAAAAAAA11PSwrDIBDdB3KHtzSbQLIt6aYnETNtBKtFJ21K8e6NiabQjeD7Dy0P5xnKyBBwSW8PWpjsmL8dPnUFKGcD%2B1mx86LZIYAnHdo78eTGDgNkeFuFlR7ORQEYYjyl704F2JJwna1i7WzyZUdcJUWUHCnxJTXnWbmoF80RtdNHlGgKAbQ8kRV%2FW0q9M9QadxOp5ZcGxBwQNyzucwJL1iofd2xY59ZV%2FAKaNp8cPgEAAA%3D%3D&config=H4sIAAAAAAAAA22TQZLjIAxF7%2BJ1Fl29mEUfYHZ9BkoB4ZDByIVEOq5U7t7CsXGczM56%2FhLiS9y6M9vu69aNkBlz%2FeIpCVy7rw7tAGxzGKU7qEyRh8h4P3QCuUepEv78%2BPzQ35GIcREcuiGk4KdazNIwZmSu35pUBkzCTQc504%2BGkotGR6KIkN5iA2xCEuwxb6mWYoSR0Vwgt4x6GuTAlHaoCDozZhqfaHJBAiUttjKH4Iwlhw2EjFbCBTeJ1lBJYm2sdTJDh8fS99XAhxIvEAtIq4XX2QY9seWdKLAYXxK%2FoF2nD%2FS45KIK3mSUktOqOVNIOx%2F%2BIWqfEZgTDLhlztzrHPZK%2Fx9VSF6HKFOjOuGtq4S9Xs6E4NsNa9eYJWxuZXTFYr2h3YovcHchDg4Neq9ut2T%2BCWJPWzGZRiTfQnUN%2FDaDR2jWfdrTugJv8K92Jc%2FjWPgAcnplPA1Him8lBpQTuTesRgi9wqzbex1faUkO1WZ0Tz8K17CtqQ5fyMT62lafdSE0x%2FSRjm199VEOkPq2lvcKyJUKbrN582v9092317muE38vwrnQL9TiLpcSBAAA

christiango commented 1 year ago

Thanks for a quick fix! I did a one time sponsor for your time on this.

kdy1 commented 1 year ago

Thank you so much!

swc-bot commented 1 year ago

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.