14

When I use "await" on top-level like this:

 const LuckyDrawInstance=await new web3.eth.Contract(abi)

I got a warning on the terminal: "set experiments.topLevelAwait true". When I tried to add this to "tsconfig.json", it still does not work. it says "experiments" property does not exist.

I could wrap it inside an async function but I want to set it without a wrapped function.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202

3 Answers3

40

It is nothing to do with the tsconfig.json. You have to set it inside next.config.js. New version of next.js uses webpack5 and webpack5 supports top level await.

module.exports = {
  webpack: (config) => {
    // this will override the experiments
    config.experiments = { ...config.experiments, topLevelAwait: true };
    // this will just update topLevelAwait property of config.experiments
    // config.experiments.topLevelAwait = true 
    return config;
  },
};

NOTE

You have to use it outside the functional component:

export default function Navbar() {
  // this will throw error
  // Syntax error: Unexpected reserved word 'await'.
  const provider=await customFunction()

  return (
    <section>          
    </section>
  );
}

Next 13

same setting works at "next": "^13.1.6", in both "pages" and "app" directory. (Because this feature is a webpack5 feature, not next.js feature) you can test it with this sample code:

const _promise = async () => {
  return new Promise((resolve, reject) => resolve(4));
};
// you might get typecsript warning
const val = await _promise();
console.log("val", val);

Warning

Since it is experimental, it might be broken in some versions

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • 3
    This replaces the object at config.experiments with just the given object. All other config options are wiped. Just config.experiments.topLevelAwait = true will do. +1 still as it did fix the issue – diggity May 13 '22 at 13:28
  • 1
    rather than overwriting the full web pack config object (since it could overwrite options set by other modules else you can consider merging the changes with the new option: webpack: (config) => { config.experiments = { ...config.experiments, ...{topLevelAwait: true }} return config }, – nneko Jul 22 '22 at 18:34
  • There's also an option where you just do: `config.experiments.topLevelAwait = true`. – jayg_code Oct 20 '22 at 07:03
  • 3
    in nextjs 13 this doesn't work anymore. – airtonix Feb 12 '23 at 03:08
  • @airtonix where. in app directory or both src and app? – Yilmaz Feb 12 '23 at 03:10
  • @Yilmaz bascially in the `src/pages/api/graphql.ts` , i'm spiking an experiement with this https://mahieyin-rahmun.medium.com/how-to-setup-a-graphql-server-in-next-js-with-api-endpoints-27aa4001c20b which seems a bit old and I'm already on nextjs 13 with dependencies on `next/font` – airtonix Feb 12 '23 at 03:19
  • more info: https://github.com/vercel/next.js/issues/34177 https://github.com/vercel/next.js/issues/43382 https://github.com/vercel/next.js/issues/38156 – airtonix Feb 12 '23 at 03:35
  • @airtonix it is working on next-13. I just tested – Yilmaz Feb 24 '23 at 06:32
  • @Yilmaz are you saying you tried this ☞ https://mahieyin-rahmun.medium.com/how-to-setup-a-graphql-server-in-next-js-with-api-endpoints-27aa4001c20b? can you share a minimum reproducible repo? – airtonix Feb 24 '23 at 22:31
  • @airtonix I did not follow anything. i just tested. I updated the post. have a look at – Yilmaz Feb 24 '23 at 22:35
  • @Yilmaz it would be great if you could prove it with `npx create-next-app --ts` and share it on stackblitz or codesandbox – airtonix Feb 25 '23 at 00:11
-1

The latest solution as of writing this post that worked for me is using Babel instead of SWC since Next.js does not allow custom SWC configuration, therefore, you cannot allow topLevelAwait through .swcrc file.

  1. Add Babel plugin called @babel/plugin-syntax-top-level-await into your package.json.

eg.

{
    "devDependencies": {
        "@babel/plugin-syntax-top-level-await": "^7.14.5"
    }
}
  1. Create .babelrc file in the root directory of your project where package.json lives.

  2. Inside .babelrc make sure to include next/babel preset and the topLevelAwait plugin.

eg.

{
    "presets": ["next/babel"],
    "plugins": [
        "@babel/plugin-syntax-top-level-await"
    ]
}

This is the easiest solution until Next.js team allows us to include SWC configuration. Note that by doing this you will not have SWC performance benefit since it will be disabled in favor of Babel.

Daw588
  • 56
  • 6
-4

I have been struggling with this for 2-3 days. Here is a solution that works. Please follow the following steps.

1. Copy paste the following in your package.json

{
  "name": "projectname",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha",
    "dev": "next dev"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@truffle/hdwallet-provider": "^2.0.1",
    "fs-extra": "^10.0.0",
    "ganache-cli": "^6.12.2",
    "mocha": "^9.1.4",
    "next": "^12.0.8",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "solc": "^0.8.9",
    "web3": "^1.7.0",
    "@babel/plugin-syntax-top-level-await": "^7.14.5"
  },
  "devDependencies": {
    "@babel/plugin-syntax-top-level-await": "^7.14.5"
  }
}

2. Delete your node_modules folder

3. Goto your project's root directory and reinstall all the packages using npm install command

4. Create a new file in your project's root directory and call it "next.config.js"

5. Copy paste following code in next.config.js file and save.

module.exports = {
  // target: 'experimental-serverless-trace',
  webpack: (config) => {
    config.experiments = config.experiments || {};
    config.experiments.topLevelAwait = true;
    return config;
  },
};

enter image description here

GKV
  • 864
  • 1
  • 12
  • 25