使用ts-node-dev时,顶级await引发模块导入错误求助
解决ts-node-dev下ES模块与顶级await的兼容问题
我之前也碰到过一模一样的情况,在Node 14 + TypeScript 4.x环境里用ts-node-dev启用ES模块和顶级await时,踩了好几个配置兼容的坑。下面是我亲测有效的解决方案:
核心问题根源
ts-node-dev底层依赖的ts-node默认走CommonJS模块解析逻辑,哪怕你在package.json里设了"type": "module",ts-node也不会自动切换到ESM模式——这就是你看到Cannot use import statement outside a module报错的原因。而顶级await只支持ES模块,所以必须强制让ts-node明确启用ESM处理规则。
分步解决步骤
1. 调整tsconfig.json的ts-node配置
在tsconfig.json的ts-node字段里加"esm": true,直接告诉ts-node要启用ESM模式:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "node", "outDir": "dist", "sourceMap": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true }, "ts-node": { "files": true, "transpileOnly": true, "esm": true // 新增这一行,启用ESM支持 }, "include": ["src/**/*.ts", "declariations/**.d.ts"], "exclude": ["node_modules", ".vscode"] }
2. 修改package.json的启动脚本
在tsnd命令里追加--esm参数,强制ts-node-dev以ESM模式运行服务:
{ "name": "", "version": "1.0.0", "description": "microservice", "main": "src/index.ts", "author": "", "type": "module", "license": "MIT", "scripts": { "dev": "NODE_ENV=development tsnd --respawn --files --esm src/index.ts", "prod": "NODE_ENV=production tsnd --respawn --transpile-only --files --esm src/index.ts", "test": "mocha --exit -r ts-node/register tests/**/*.spec.ts", "eslint": "eslint src/**/*.ts" } }
3. 升级ts-node-dev到兼容版本
如果上面两步做完还是报错,建议把ts-node-dev升级到1.1.6及以上的版本——旧版本对ESM的支持有明显缺陷:
npm install ts-node-dev@latest --save-dev
额外注意点
- Node 14.x的ESM支持虽然稳定,但本地文件导入最好加上完整扩展名(比如
.ts),避免解析出错; - 你的TypeScript版本(4.0+)和
module: ESNext的配置已经满足顶级await的要求,不用调整这部分; - 测试脚本里的mocha如果也需要支持ESM,可能还要单独配置,但先搞定服务启动的问题再处理测试场景更稳妥。
按上面的步骤调整后,应该就能正常用顶级await,也不会再出现模块相关的报错了。
内容的提问来源于stack exchange,提问作者treeden




