xojs/xo

Automatic ecmaVersion

sholladay opened this issue · 2 comments

It would be nice if XO had a reasonable default for ecmaVersion, perhaps based on the engines config in package.json. Or even just ecmaVersion: 'latest'.

The reason is that XO requires usage of top-level await:

fetch().then();
  example.js
  ✖  1:9  Prefer top-level await over using a promise chain.  unicorn/prefer-top-level-await

Yet, by default, it cannot actually be parsed:

await fetch();
  example.js
  ✖  1:1  Parsing error: Cannot use keyword await outside an async function

The solution is simple but not well-known:

"xo": {
    "parserOptions": {
        "ecmaVersion": "2022"
    }
}

That's a bit annoying, but also I don't think developers generally think in terms of which ECMAScript version they are targeting. Rather, we think, "What does my target runtime support?" In other words, we want to use whatever language features are supported by Node vX.Y.Z. I know that XO already looks up the engines config to determine support for certain Node-specific features. Maybe that could be used to set a reasonable default for ecmaVersion, too? If that's not feasible, would latest be an okay default? Whatever the current default is, it's years out of step with all common runtimes. For example, top-level await shipped unflagged in Node v14.8.0 on 2020-08-11 and Safari v15 on 2021-09-20.

Module Version
xo 0.56.0
eslint-config-xo 0.34.0

ecmaVersion: 'latest',

Thanks! Looks like this actually has to do with my shareable config eslint-config-tidy. I didn't think that could be the problem since my config doesn't set ecmaVersion. However, it is extending eslint:recommended and an old version of the xo/esnext config, and it turns out that xo/esnext does set ecmaVersion to a hardcoded 2021 via https://github.com/xojs/eslint-config-xo/blob/eafbd8fcbe40abdb34c9c9273b6850c49cf585b8/index.js#L5.

So, this is definitely behaving as expected.

My config setup might be a bit silly. I think my goal at the time was to ensure that eslint-config-tidy could be used independently of XO. Maybe I should rethink that decision.

In the end:

  • Without any XO config, the await fetch() works fine with no errors - should've tried this first
  • With this config it errors as I originally described:
    "devDependencies": {
        "eslint-config-tidy": "^0.11.0",
        "xo": "^0.56.0"
    },
    "xo": {
        "extend": "tidy"
    }
  • With this config we are back to no errors, which made me think this was an XO issue:
    "devDependencies": {
        "eslint-config-tidy": "^0.11.0",
        "xo": "^0.56.0"
    },
    "xo": {
        "extend": "tidy",
        "parserOptions": {
            "ecmaVersion": "2022"
        }
    }