TS Node+ES模块项目运行报错:ERR_UNKNOWN_FILE_EXTENSION或ERR_MODULE_NOT_FOUND
问题根因
你遇到的报错由两个核心规则冲突导致:
- Node原生ESM模式下,不会自动补全模块导入的后缀名,你写
import './app'时,Node只会严格匹配无后缀的app文件,不会主动查找app.ts/app.js - ts-node默认使用CommonJS模式解析文件,和
package.json中配置的"type": "module"不兼容
分步解决方案
- 所有相对路径导入语句统一补全
.js后缀,注意不是.ts:
比如将import app from './app'改为import app from './app.js',TS编译时会自动匹配对应的.ts源文件,编译后也会保留符合ESM规范的后缀。 - 修改
tsconfig.json配置,新增/调整以下字段:{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "target": "ESNext", "esModuleInterop": true, "outDir": "./dist" }, "ts-node": { "esm": true }, "include": ["src/**/*"] } - 直接运行TS文件时,执行以下命令即可:
ts-node src/server.ts
不需要手动添加--loader参数,tsconfig中的ts-node配置段已经开启了ESM兼容。 - 先编译再运行的场景:
执行tsc完成编译后,直接运行node dist/src/server.js即可,不需要额外加ts-node相关loader参数。
ESM适配成本高的原因
Node的ESM规范落地远晚于CommonJS生态,包括TS、ts-node在内的绝大多数工具链最早都是基于CommonJS规则设计,兼容ESM需要做大量改造。同时ESM本身有很多严格限制(必须带后缀、导入路径规则严格、不支持CommonJS专属全局变量等),和之前CommonJS的松散开发习惯差异很大,叠加TS的编译层后,就容易出现很多反直觉的报错。
内容的提问来源于stack exchange,提问作者ilmoi
相关产品推荐
相关产品推荐

