Uglifyjs: [ES8] async/await not supported also in harmony

Created on 5 Apr 2017  路  18Comments  路  Source: mishoo/UglifyJS

Hello,

async/await are now supported by a large browser base by default ( http://caniuse.com/#search=await ), only Microsoft Edge requires a flag to be enabled.

But UglifyJS, also in harmony doesn't support this feature yet. I got this error:

Unexpected token: keyword (function)

on code as:

async function connect() { //async code }

I think it's a really important feature for javascript to be supported.

harmony

Most helpful comment

async support in [email protected]

All 18 comments

+1 Same issue

It's a fair bit of work involved to add ES2017 async/await to uglify-es (a.k.a. harmony).

If someone is interested in implementing it, here's an outline:

  • add an async boolean property to AST_Lambda
  • create a new expression type AST_Await
  • parser support

    • async is not a reserved word - it can also be an identifier in other contexts.

    • await identifier issues

    • function declaration

    • function expression

    • arrow function

    • concise methods in object literals

    • class method



      • static


      • regular



    • cannot combine async with setters, getters and generators

  • transform support
  • compress

    • must disable certain optimizations on async functions and await expressions

    • not likely any optimization opportunities

  • output support

    • mirror of parser support

  • tests
  • mozilla conversion functions (optional, can be done later)

Resources:

The proposed AST_Await class would be very similar to AST_Yield which was implemented in #1104. AST_Await would also have a single child expression, although the precedence of the await expression is different than yield, and the expression is mandatory in await.

No need for an async class - it would just be a new property on AST_Lambda and AST_ConciseMethod. It would be much like is_generator is for AST_Yield.

@alexlamsl I have a first cut implementation of async/await for uglify-es but I need master to be merged to harmony as a prerequisite for this patch. Need to disallow the inline optimization for async functions. The IIFE parameter substitution optimization also might not be safe for async functions - I have to think about that.

@kzc cool - I'll make a release later on today then.

So far the patch covers most async/await use cases except for async arrow function expressions. Parsing them without backtracking is challenging because async is not a reserved word and code like the following is valid ES2017:

let x = 1, async = function async(){}; async (x); async (x) => await x + x;

@alexlamsl After you merge master to harmony I'm inclined to create a PR with the work I have so far. If you're inspired to get async arrow function expressions working at that point, feel free.

Cool, and I think I'll get your PR in before cutting the harmony release.

@kzc FYI, master now merged into harmony via #2094

Great - I'll rebase.

@alexlamsl I need some help getting the correct options for the following test to be inlined as just console.log("top"); so that I can test the async equivalent is not inlined:

    options = {
        inline: true,
        conditionals: true,
        evaluate: true,
        negate_iife: true,
        side_effects: true,
        toplevel: true,
        unused: true,
    }
    input: {
        function top() { console.log("top"); } top();

CLI works fine:

$ echo 'function top() { console.log("top"); } top();' | bin/uglifyjs -c toplevel
console.log("top");

Nevermind - it was reduce_vars: true that was needed.

reduce_vars (marking top)
https://github.com/mishoo/UglifyJS2/blob/8af362ed57ab6d236f87abe76301f50928153661/lib/compress.js#L358

unused (function top() { console.log("top"); } top(); :arrow_right: (function() { console.log("top"); })();)
https://github.com/mishoo/UglifyJS2/blob/8af362ed57ab6d236f87abe76301f50928153661/lib/compress.js#L4069

inline ((function() { console.log("top"); })(); :arrow_right: void console.log("top");)
https://github.com/mishoo/UglifyJS2/blob/8af362ed57ab6d236f87abe76301f50928153661/lib/compress.js#L3390

side_effects (void console.log("top"); :arrow_right: console.log("top");)
https://github.com/mishoo/UglifyJS2/blob/8af362ed57ab6d236f87abe76301f50928153661/lib/compress.js#L2709

Man, it's hard to remember all the interactions between the options. I just cut/paste all the settings and removed them one by one. :-)

@kzc whatever works best for you - I'm happy to be the clean-up crew :sunglasses:

2098 implements async/await - except for async arrow functions.

Now that #2098 has been merged to harmony, this issue can be closed in favor of #2102.

async support in [email protected]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Havunen picture Havunen  路  5Comments

chrismanley picture chrismanley  路  5Comments

utdrmac picture utdrmac  路  4Comments

diegocr picture diegocr  路  3Comments

buu700 picture buu700  路  5Comments