Node.js TypeScript ES模块项目无法使用绝对路径的问题
问题:ESM模式下Node.js/TypeScript无法使用绝对路径导入
我在搭建Node.js/TypeScript(NestJS)项目时,为了使用顶层Await特性将项目设置为ES模块(在package.json中添加了"type": "module"),但遇到了绝对路径导入的问题:
- VSCode能通过tsconfig识别绝对路径(比如
import { PrismaService } from "src/prisma/prisma.module.js"),无语法报错 - 项目编译正常,但运行时抛出错误:
Error: Cannot find package 'src' imported from C:\User.... - 切换为CommonJS模式时,绝对路径可正常使用,但无法使用顶层Await
当前核心配置:
- package.json:
"type": "module"
- tsconfig.json(关键项):
{ "compilerOptions": { "module": "ES2022", "baseUrl": "./", "moduleResolution": "NodeNext", "paths": { "src/*": ["./src/*"] } // 其他配置略 } }
解决方法
原因说明
ES模块(ESM)模式下,Node.js不会读取tsconfig.json中的paths配置——VSCode能识别路径是因为它依赖tsconfig做语法检查,但运行时Node会直接把src/xxx当作第三方包去node_modules查找,自然找不到。
方案1:使用Node.js官方Subpath Imports(推荐,无额外依赖)
通过package.json的imports字段定义路径映射,这是Node.js原生支持的ESM路径别名方案:
- 在package.json中添加:
"imports": { "#src/*": "./src/*" }
- 更新tsconfig.json的
paths,让TypeScript识别这个别名:
"paths": { "#src/*": ["./src/*"] }
- 代码中使用别名导入:
import { PrismaService } from "#src/prisma/prisma.service.js";
方案2:用第三方工具自动处理路径映射
如果想保留src/开头的导入方式,可以用以下工具实现:
方式A:使用tsx(简便高效)
tsx是TypeScript的运行时工具,会自动读取tsconfig的paths并处理ESM路径:
- 安装依赖:
npm install -D tsx
- 修改启动脚本:
"scripts": { "start": "tsx src/main.ts" }
方式B:使用ts-node + tsconfig-paths
- 安装依赖:
npm install -D ts-node tsconfig-paths
- 修改启动脚本:
"scripts": { "start": "node --loader ts-node/esm --require tsconfig-paths/register src/main.js" }
额外注意事项
- ESM模式下,所有导入必须带完整扩展名(比如
.js,即使是TypeScript文件,因为编译后输出为JS),你当前的代码已经满足这一点,无需修改。 - 确保tsconfig的
moduleResolution设置为NodeNext或Node16,和module: ES2022保持匹配。
内容的提问来源于stack exchange,提问作者ShueiYang
相关产品推荐
相关产品推荐

