如何在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模块语法,原生支持顶层awaitmoduleResolution: 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使用说明
- 无需改用
.mjs/.js文件:只要上述配置到位,直接在.ts文件中使用顶层await完全合法。 - 导出非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
相关产品推荐
相关产品推荐

