Skip to content
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

Allow top-level await #409

Closed
ehmicky opened this issue Feb 19, 2019 · 18 comments
Closed

Allow top-level await #409

ehmicky opened this issue Feb 19, 2019 · 18 comments

Comments

@ehmicky
Copy link

ehmicky commented Feb 19, 2019

It seems like top-level await expressions are not allowed:

> espree.parse('await true')
Thrown:
{ [SyntaxError: Unexpected token true
] index: 6, lineNumber: 1, column: 7 }

Should they be enabled? One reason could be that there is a proposal for top-level await.

But actually my use case is when using ESLint inside Markdown files with eslint-plugin-markdown. Documentations might contain one liners that miss the context (i.e. the async function keyword) in order to be shorter.

For example let's say I have a module dummy that returns a promise. I might want to document it like this:

`dummy` returns a promise and take an options object as argument:

``​`js
const returnValue = await dummy(options)
``​`

Acorn has a allowAwaitOutsideFunction option that does this.

@mysticatea
Copy link
Member

mysticatea commented Feb 19, 2019

Thank you for this issue.

As README.md described, we support only stage 4 syntax in general: https://github.com/eslint/espree#how-do-you-determine-which-experimental-features-to-support

But Markdown use case sounds reasonable to me, and we don't need any acorn plugins to implement this.

For now, I guess you can use babel-eslint.

@nzakas
Copy link
Member

nzakas commented Feb 19, 2019 via email

@ehmicky
Copy link
Author

ehmicky commented Feb 19, 2019

Would supporting be difficult for them without the parser (espree) supporting it?

Also this might not be specific to Markdown. E.g. the same problem could arise when linting JavaScript embedded in HTML.

@not-an-aardvark
Copy link
Member

I'd be fine with adding a parser option for this which just passes through to the acorn option.

@nzakas
Copy link
Member

nzakas commented Feb 20, 2019

I'd rather not get into the habit of supporting one-off proposals again. Top-level await is only at stage 2, which falls outside of our defined support strategy. babel-eslint is the right choice for using experimental features.

Given that the request here isn't actually to support top-level await in JavaScript files, but rather to enable the ability to document things inside of Markdown, it seems like the easiest workaround here is just to document it like this:

`dummy` returns a promise and take an options object as argument:

``​`js
(async () => {

    const returnValue = await dummy(options)

})();
``​`

Arguably, that's a better way to document such a function, as it may not be clear to all consumers that await can't be used at the top level.

@ehmicky
Copy link
Author

ehmicky commented Feb 20, 2019

I agree with @nzakas that my request is actually not about top-level await, in which case babel-eslint would be have been more proper since this is a stage 2 proposal.

The code above is actually the workaround I am currently using. Unfortunately on a README with dozens of code examples, adding those context lines makes the documentation more verbose (which really was the thing that triggered me into submitting this issue).

Also the code above involves getting a returnValue without using it, which might confuse some developers. When it's a one liner example, one can assume the next lines are missing, explaining why returnValue is not used. Since the context is missing I think developers might not assume those one liners are meant to be performed in the top-level scope, but are instead part of another function.

However if you think this workaround is enough for this use case, I will keep using it and close this issue.

@ilyavolodin
Copy link
Member

I think in the case you are describing, the proper way of fixing it is by cloning and extending processor for Markdown to append closure around your examples. That way, you can continue to display what looks like top level await, but it would be valid JS code when it's passed to ESLint.

@nzakas
Copy link
Member

nzakas commented Mar 7, 2019

@ehmicky I think there are multiple ways to solve this without needing Espree to change. @ilyavolodin's suggestion is another good one. You can definitely create a processor that inserts the appropriate text in order for ESLint to parse it and then format the results to point to the correct location.

@ehmicky
Copy link
Author

ehmicky commented Mar 7, 2019

Thanks for looking into it, I am closing this issue then.

I unfortunately don't have the time to create a Markdown processor to solve this issue. I've opened an issue with eslint-plugin-markdown to see if my original problem could be solved in other ways.

@ehmicky ehmicky closed this as completed Mar 7, 2019
@futpib
Copy link

futpib commented Jul 3, 2020

I want this and top-level yield so much (under globalAwait and globalYield options). Is globalReturn standard? It is supported, so I hope await and yield should be too.

@dmail
Copy link

dmail commented Sep 7, 2021

This should be reconsidered, top level await is now part of the spec

@aladdin-add
Copy link
Member

it has been landed in #505

@dmail
Copy link

dmail commented Sep 7, 2021

I don't understand why I get the following error:

> node ./node_modules/eslint/bin/eslint.js .

/Users/dmail/experiment/top_level_await/top_level_await.js
  1:1  error  Parsing error: Cannot use keyword 'await' outside an async function

✖ 1 problem (1 error, 0 warnings)

.eslintrc.cjs

module.exports = {
  parserOptions: {
    ecmaVersion: 2021,
    sourceType: "module",
  },
}

top_level_await.js

await Promise.resolve(42)

eslint in my package.json is 7.32.0

@aladdin-add
Copy link
Member

it will be supported in eslint v8(still in beta).

@dmail
Copy link

dmail commented Sep 7, 2021

Wonderful thank you !
(I confirm it works with 8.0.0-beta.1, I will use beta version 👍 )

@aladdin-add
Copy link
Member

also, to use TLA, you'lll need to set ecmaVersion: 2022

@dmail
Copy link

dmail commented Sep 7, 2021

you'lll need to set ecmaVersion: 2022

Indeed, I tried when I saw the pull request changes 👌

Apparently ESLint beta is not compatible with vscode-eslint.

The eslint library loaded from /Users/dmail/node_modules/eslint/lib/api.js doesn't export a CLIEngine. You need at least eslint@1.0.0)

I guess I have to stick to "@babel/eslint-parser" for now.

@ota-meshi
Copy link
Member

Hi @dmail!
It works with ESLint v8 (beta) by using the insider version of vscode-eslint. If you want to try it out, download vsix from the release page and install it in VSCode.
https://github.com/microsoft/vscode-eslint/releases/tag/release%2F2.1.24-Insider

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants