如何在TypeScript Next.js中使用顶级的"await"?

15

当我在顶层使用“await”时,就像这样:

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

我在终端上收到了一个警告:“set experiments.topLevelAwait true”。当我尝试将其添加到“tsconfig.json”中时,它仍然无法工作。它提示“experiments”属性不存在。

我可以将其包装在async函数中,但我希望不使用包装函数来设置它。

3个回答

41

这与tsconfig.json无关。您需要在next.config.js中进行设置。Next.js的新版本使用webpack5,而webpack5支持顶级等待。

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;
  },
};

注意

您必须在函数组件之外使用它:

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

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

Next 13

相同的设置在 "pages" 和 "app" 目录中都可以使用 "next": "^13.1.6",因为这个功能是 webpack5 的功能,而不是 next.js 的功能。您可以使用此示例代码进行测试:

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

警告

由于这是一个实验性功能,在某些版本中可能存在故障问题。


3
这将用给定的对象替换config.experiments中的对象。所有其他配置选项都将被清除。只需设置config.experiments.topLevelAwait = true即可。它仍然有效,因为它修复了问题。 - diggity
1
与其覆盖整个 Webpack 配置对象(因为它可能会覆盖其他模块设置的选项),你可以考虑将更改与新选项合并: webpack: (config) => { config.experiments = { ...config.experiments, ...{topLevelAwait: true }} return config }, - nneko
3
在 Next.js 13 中,这个不再起作用了。 - airtonix
@Yilmaz,你是在说你尝试过这个吗 ☞ https://mahieyin-rahmun.medium.com/how-to-setup-a-graphql-server-in-next-js-with-api-endpoints-27aa4001c20b?你能分享一个最小可复现的仓库吗? - airtonix
@airtonix 我没有遵循任何东西。我只是测试了一下。我更新了帖子。请看一下。 - Yilmaz
显示剩余6条评论

-1
截至本文撰写时,对我有效的最新解决方案是使用Babel而不是SWC,因为Next.js不允许自定义SWC配置,因此您无法通过.swcrc文件允许topLevelAwait。
1.将名为@babel/plugin-syntax-top-level-await的Babel插件添加到您的package.json中。
例如:
{
    "devDependencies": {
        "@babel/plugin-syntax-top-level-await": "^7.14.5"
    }
}
  1. 在项目根目录下创建一个.babelrc文件,它应该和package.json文件处于同一级目录。

  2. .babelrc文件中,确保包含next/babel预设和topLevelAwait插件。

例如:

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

这是最简单的解决方案,直到Next.js团队允许我们包含SWC配置。请注意,通过这样做,您将不会获得SWC性能优势,因为它将被禁用以支持Babel。


1
如果您在Next.js 13中这样做,就不能再使用next/font包了。 - airtonix

-4

我已经苦恼了2-3天。这是一个可行的解决方案,请按照以下步骤进行。

1. 将以下内容复制粘贴到您的 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. 删除你的node_modules文件夹

3. 进入你的项目根目录并使用npm install命令重新安装所有包

4. 在你的项目根目录中创建一个名为"next.config.js"的新文件

5. 将以下代码复制粘贴到next.config.js文件中并保存。

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

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接