在新TypeScript项目配置顶层await时遭遇文件扩展名错误
问题:TypeScript + ts-node + nodemon 启动报错 ERR_UNKNOWN_FILE_EXTENSION
我是TypeScript新手,测试以下脚本时持续报错:
// ./src/index.ts import fetch from 'node-fetch'; const getResp = await fetch('https://jsonplaceholder.typicode.com/todos/1');
错误信息
[nodemon] 2.0.19 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): '.\**\*.ts' [nodemon] watching extensions: ts,json [nodemon] starting `ts-node src/index.ts` TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" at new NodeError (internal/errors.js:322:7) at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:71:15) at Loader.getFormat (internal/modules/esm/loader.js:105:42) at Loader.getModuleJob (internal/modules/esm/loader.js:243:31) at async Loader.import (internal/modules/esm/loader.js:177:17) at async Object.loadESM (internal/process/esm_loader.js:68:5) at async handleMainPromise (internal/run_main.js:59:12) { code: 'ERR_UNKNOWN_FILE_EXTENSION' }
环境与配置
- 系统:Windows 11
- Node版本:14.19.0
- 目标:编写TypeScript代码,自动编译到构建目录并快速测试
package.json
{ "name": "heroku-stack-api", "version": "1.0.0", "description": "", "main": "index.js", "type": "module", "scripts": { "dev": "nodemon --watch './**/*.ts' --exec \"ts-node\" src/index.ts", }, "devDependencies": { "@types/node": "^14.18.22", "gts": "^3.1.0", "nodemon": "^2.0.19", "ts-node": "^10.9.1", "typescript": "^4.7.4" }, "dependencies": { "cheerio": "^1.0.0-rc.12", "node-fetch": "^3.2.8" } }
tsconfig.json
{ "compilerOptions": { "esModuleInterop": true, "exactOptionalPropertyTypes": true, "isolatedModules": true, "lib": [ "esnext" ], "module": "esnext", "moduleResolution": "node", "noUncheckedIndexedAccess": true, "outDir": "dist", "strict": true, "target": "esnext", "useUnknownInCatchVariables": true }, "include": [ "./src/**/*" ] }
nodemon.json
{ "watch": "src/**/*.ts", "execMap": { "ts": "ts-node" } }
解决方案
问题根源是启用了"type": "module"(ESM模式),但ts-node处理ESM需要额外配置,加上Node 14对ESM的支持有限,按以下步骤修改:
- 修改package.json的dev脚本
替换原有dev脚本为:
"dev": "nodemon --exec ts-node-esm src/index.ts"
ts-node-esm是ts-node专门用于处理ESM模块的执行命令,替代默认的ts-node。
- 调整tsconfig.json配置
将moduleResolution改为"nodenext"(Node 14+支持),同时添加ts-node配置段明确ESM模式:
{ "compilerOptions": { // 保留原有配置 "moduleResolution": "nodenext" }, "include": ["./src/**/*"], "ts-node": { "esm": true } }
- 修复顶层await问题
Node 14不支持顶层await,需将代码包裹在async立即执行函数中:
// ./src/index.ts import fetch from 'node-fetch'; (async () => { const getResp = await fetch('https://jsonplaceholder.typicode.com/todos/1'); const data = await getResp.json(); console.log(data); })();
(若升级Node到16+,可直接使用顶层await)
- 简化nodemon配置(可选)
删除nodemon.json,直接在package.json脚本中配置,避免冲突:
"scripts": { "dev": "nodemon --watch src/**/*.ts --exec ts-node-esm src/index.ts", "build": "tsc" }
新增的build脚本可将TypeScript编译到dist目录。
完成以上修改后,运行npm run dev即可正常启动并测试代码。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

