vitejs/vite

Top-level await is not supported by `ssrLoadModule`

Rich-Harris opened this issue ยท 4 comments

Describe the bug

If a module uses top-level await, attempting to load it with ssrLoadModule results in an error.

Stack trace
4:03:16 PM [vite] Error when evaluating SSR module src/index.js:
SyntaxError: Cannot use keyword 'await' outside an async function (2:0)
    at Object.pp$5.raise (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47485:13)
    at Object.pp$4.checkUnreserved (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47391:14)
    at Object.pp$4.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47421:10)
    at Object.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49866:27)
    at Object.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49948:27)
    at Object.pp$4.parseExprAtom (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46784:19)
    at Object.pp$4.parseExprSubscripts (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46652:19)
    at Object.pp$4.parseMaybeUnary (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46618:17)
    at Object.parseMaybeUnary (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49793:29)
    at Object.pp$4.parseExprOps (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46551:19)
node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

SyntaxError: Cannot use keyword 'await' outside an async function (2:0)
    at Object.pp$5.raise (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47485:13)
    at Object.pp$4.checkUnreserved (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47391:14)
    at Object.pp$4.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:47421:10)
    at Object.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49866:27)
    at Object.parseIdent (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49948:27)
    at Object.pp$4.parseExprAtom (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46784:19)
    at Object.pp$4.parseExprSubscripts (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46652:19)
    at Object.pp$4.parseMaybeUnary (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46618:17)
    at Object.parseMaybeUnary (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:49793:29)
    at Object.pp$4.parseExprOps (/path/to/vite-top-level-await-repro/node_modules/vite/dist/node/chunks/dep-36bf480c.js:46551:19) {
  pos: 43,
  loc: Position { line: 2, column: 0 },
  raisedAt: 52
}

As an aside, npx vite build in the provided repro fails because the esbuild: false config option isn't being respected for some reason. That's unrelated to this issue but I figured I'd mention it in case there's a user error that's obvious to people who aren't me.

Reproduction

https://github.com/Rich-Harris/vite-top-level-await-repro

System Info

System:
    OS: macOS 10.15.7
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 5.66 GB / 64.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 16.5.0 - ~/.nvm/versions/node/v16.5.0/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 7.19.1 - ~/.nvm/versions/node/v16.5.0/bin/npm
  Browsers:
    Chrome: 93.0.4577.82
    Firefox: 92.0
    Safari: 14.1.2
  npmPackages:
    vite: ^2.5.2 => 2.5.10

Used Package Manager

npm

Logs

No response

Validations

ygj6 commented

Vite uses acorn as a JavaScript parser to parse the transformed source code:

export let parser = acorn.Parser.extend(
acornClassFields,
acornStaticClassFeatures
)

const ast = parser.parse(code, {
sourceType: 'module',
ecmaVersion: 2021,
locations: true
}) as any

According to the document of acorn:

allowAwaitOutsideFunction: If false, await expressions can only appear inside async functions. Defaults to true for ecmaVersion 2022 and later, false for lower versions. Setting this option to true allows to have top-level await expressions. They are still not allowed in non-async functions, though.

So we can modify the Vite's source code of the parser options to ecmaVersion: 2022 or allowAwaitOutsideFunction: true to take effect the code of data.js.

Waiting for core members to respond ๐Ÿ‘€.

We can bump it to 2022, it is the same reason for the latest commit from Evan that modified that field 407ce3b. Would you send that PR @ygj6?

ygj6 commented

We can bump it to 2022, it is the same reason for the latest commit from Evan that modified that field 407ce3b. Would you send that PR @ygj6?

OK, I will do it soon.

thanks for such a speedy diagnosis and fix!