Skip to content

English__JavaScript Concepts__Top Level Await

Ramirez Vargas, José Pablo edited this page Nov 7, 2024 · 4 revisions

Top-Level Await

This feature is a relatively new JavaScript feature and it allows developers to await any promise anywhere, not just inside asynchronous functions. This is only available for ES Modules, so don't go looking for this feature in CommonJS modules, as it will never be there.

Why wj-config Requires Top-Level Await

Building the final configuration object is an asynchronous operation by design to allow asynchronous data sources such as fetching configuration from an HTTP server.

Strictly speaking, it is not a hard requirement. As seen in the examples in wj-config's repository, or even the introductory page in this wiki, it is possible to use wj-config in CommonJS modules. The syntax, in turn, suffers.

At the time this documment was written, all major browsers supported top-level awaits as seen in the can I use website. Yes, NodeJS and Deno support top-level awaits as well. This should bring you confidence about enabling it if your current framework has it disabled by default, which seems to be the trend.

Enabling Top-Level Await in React Projects (CRA)

If you have a React project created with Create React App then you can enable top-level awaits in two ways:

  1. Eject. By ejecting using npm run eject (read more) you gain direct access to the configuration for webpack.
  2. Install @craco/craco. After installing you may write your own webpack configuration.

You'll find many posts and comments all over the Internet that discourage ejecting, so this wiki won't be encouraging it either. Instead, let's see about the second option.

Configuring Webpack with CRACO

This is the simplest thing in the world. Just install @craco/craco and then create the craco.config.js file at the same level as the /src folder, which is usually your project's root. The necessary contents to enable top-level awaits is:

module.exports = {
    webpack: {
        configure: {
            experiments: {
                topLevelAwait: true
            }
        }
    }
}

This is all that is needed.

Enabling Top-Level Await in Vite

Vite supports several browser libraries, not just React, and the process is the same. The following sample is the one found in the Vue sample for wj-config; the file is vite.config.ts at the root of the project:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  build: {
    target: "es2022"
  },
  server: {
    port: 3007
  }
})

The part that enables top-level await is the build.target one. By targetting EcmaScript 2022, you are granted top-level await. Yes, other values may grant it too, such as esnext.