You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript、Node及Stencil JS中启用顶层await?

解决方案:TypeScript + Node + Stencil JS 启用顶层await

报错核心原因

你遇到的报错是因为编译后的模块仍被识别为CommonJS(CJS)格式,即使tsconfig.json中设置了module: ESNext,也可能因为Node环境默认解析规则或Stencil构建配置的冲突,导致最终输出还是CJS,而CJS不支持顶层await。


一、正确的TypeScript配置(tsconfig.json)

确保以下关键配置项:

{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "NodeNext",
    "target": "ES2020",
    "outDir": "./dist",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src/**/*"]
}
  • module: ESNext:启用ES模块语法,原生支持顶层await
  • moduleResolution: NodeNext:匹配Node.js的ES模块解析规则,避免CJS/ES模块混淆
  • target: ES2020:顶层await在ES2020中正式纳入标准,确保编译后的代码兼容

二、Node.js环境适配

在项目根目录的package.json中添加:

{
  "type": "module"
}

这会强制Node.js将所有.js/.ts文件默认当作ES模块处理,避免把编译后的ES模块误判为CJS。


三、Stencil JS构建配置调整(stencil.config.ts)

Stencil默认输出ES模块,但需确保没有强制输出CJS的配置:

import { Config } from '@stencil/core';

export const config: Config = {
  namespace: 'your-component-library',
  outputTargets: [
    {
      type: 'dist',
      esmLoaderPath: '../loader',
    },
    {
      type: 'dist-custom-elements',
    }
  ],
  // 禁用或移除输出CJS格式的配置项
};

顶层await使用说明

  1. 无需改用.mjs/.js文件:只要上述配置到位,直接在.ts文件中使用顶层await完全合法。
  2. 导出非Promise对象:你的示例代码是可行的——当其他模块import { hello } from './Hello.ts'时,Node/Stencil会自动等待顶层await的Promise完成,最终拿到的是"Hello World"字符串(而非Promise)。
    • 注意:包含顶层await的模块会变成异步模块,所有依赖它的模块都会等待其加载完成,需注意组件初始化的时序问题。

验证示例代码

配置完成后,你的代码可以直接运行:

// Hello.ts
export class Hello {
  static async SayHello() {
    return new Promise(resolve => {
      resolve("Hello World");
    });
  }
}

export const hello = await Hello.SayHello();
// index.ts
import { hello } from './Hello.ts';
console.log(hello); // 输出: Hello World

内容的提问来源于stack exchange,提问作者runr2002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:07:05