typescript 默认在 `module: “esnext”` 下移除导入路径中的 `.js` 后缀,导致 node.js esm 环境无法解析模块;需通过 `verbatimmodulesyntax: true`(推荐)或 `allowjs: true` 配合正确配置来保留扩展名。
在 TypeScript 5.0+ 中,allowJs: true 并不能真正解决 .js 后缀缺失问题——它仅允许 TS 编译器读取 .js 文件,但不会影响输出的 import 语句生成逻辑。官方文档也明确指出:allowJs 与模块路径重写无关。真正有效的方案是启用 verbatimModuleSyntax: true(自 TS 4.7 起引入),该选项强制 TypeScript 原样保留源码中 import/export 语句的路径字符串,包括 .js 扩展名。
✅ 正确解决方案:启用 verbatimModuleSyntax
更新你的 tsconfig.json,添加以下关键配置:
{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2020", "esnext.asynciterable"],
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"verbatimModuleSyntax": true // ? 关键:保留原始 import 路径(含 .js)
}
}
✅ 效果:
若你在 User.ts 中显式写为:
import { UserFavoriteRoom } from "./UserFavoriteRoom.js";
import { Room } from "./Room.js";
则编译后 User.js 将严格保持: