javascriptnode.jsbabeljstop-level-await

Babel preset-env not loading top-level await syntax for node target


I am trying out the new top-level await syntax to import a module, but Babel is not recognizing the syntax, despite using preset-env, unless I explicitly set the plugin @babel/plugin-syntax-top-level-await. Why do I have to manually specify this plugin? I was under the impression that preset-env would take care of these things automatically?

For context, my settings are as follows:

    presets: [
      [
        '@babel/preset-env',
        {
          debug: true,
          modules: false,
          useBuiltIns: 'usage',
          corejs: 3,
        },
      ],
      '@babel/preset-typescript',
    ],
    // plugins: ['@babel/plugin-syntax-top-level-await'], // Commented b/c I was experimenting
  };

When running yarn run babel myFile.ts, the output and error thrown are:

@babel/preset-env: `DEBUG` option
Using targets:
{
  "node": "13.12"
}
Using modules transform: false
Using plugins:
  proposal-nullish-coalescing-operator { "node":"13.12" }
  proposal-optional-chaining { "node":"13.12" }
  syntax-json-strings { "node":"13.12" }
  syntax-optional-catch-binding { "node":"13.12" }
  syntax-async-generators { "node":"13.12" }
  syntax-object-rest-spread { "node":"13.12" }
  syntax-dynamic-import { "node":"13.12" }
Using polyfills with `usage` option:
SyntaxError: /path/to/project/src/storage/index.ts: Unexpected token, expected ";" (4:6)
  2 | import { AppError } from '../errors';
  3 | 
> 4 | await import('./db/dbDiskMethods');
    |       ^
  5 | 
  6 | const getDbDiskMethods = async () => {
  7 |   return await import('./db/dbDiskMethods');

As a side question, why does preset-env load the 5 syntax plugins shown in the debug output, but skips top-level await syntax plugin?


Solution

  • This is happening because preset-env only loads accepted proposals. Currently, top level await has not yet been accepted into the language, it's at stage 3.

    In general, list of plugins available to preset-env comes from the compat-data package. The list of plugins actually used by preset-env when Babel is run depends on

    The OP error was thrown because Babel was run from command line. Had it been run by babel-loader, the "missing" plugin would have been added automatically as mentioned in the second point above.