Node18+TS+ESM环境如何实现项目根路径模块导入
问题根因
tsconfig.json里的rootDir配置仅用于指定TS编译器的源码输入根目录,不会自动生成路径映射规则。你写的import { number } from 'check.js'属于ESM规范里的「裸导入符」,默认会被Node和TS解析为node_modules下的第三方依赖,自然找不到本地src目录下的文件。
另外你当前配置的moduleResolution: "node"是为CommonJS模块设计的,不适配Node 18+的ESM解析逻辑,同时TS的路径映射仅在编译/类型检查阶段生效,不会自动处理运行时的模块解析,所以单独配rootDir完全达不到根路径导入的效果。
可落地配置步骤
1. 修改tsconfig.json配置
调整模块解析规则适配ESM,添加路径别名映射,同时补充ts-node的ESM专属配置:
{ "compilerOptions": { "lib": [ "es6", "es2021", "es2022" ], "module": "NodeNext", "target": "ES2021", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "moduleResolution": "NodeNext", "sourceMap": true, "rootDir": "./src", "outDir": "dist", "baseUrl": "./src", "paths": { "@/*": ["./*"] } }, "ts-node": { "esm": true, "experimentalSpecifierResolution": "node" } }
说明:配置里用
@/作为源码根目录的前缀,是Node/TS生态通用的做法,ESM规范不支持修改裸导入符的解析规则,直接写check.js会和第三方npm包命名冲突,存在严重隐患,不建议使用。
2. 安装运行时路径解析依赖
TS的paths配置不会影响运行时的模块加载逻辑,需要安装对应的加载器让ts-node-esm能识别别名路径:
yarn add -D tsconfig-paths
3. 调整启动脚本
修改package.json里的dev命令,启动时加载路径解析loader:
{ "scripts": { "dev": "node --loader ts-node/esm --loader tsconfig-paths/esm src/start.ts" } }
4. 调整导入语句
把原来的导入写法改成带@/前缀的形式,@/就对应你配置的src根目录:
// 相对路径写法(可正常运行) // import { number } from './check.js' // 根路径别名写法 import { number } from '@/check.js' console.log(number)
生产环境编译补充
直接用tsc编译出来的JS代码不会自动替换别名路径,生产环境运行会报模块找不到的错误,需要额外配置路径替换:
- 安装依赖:
yarn add -D tsc-alias
- 修改build脚本,编译完成后自动替换别名路径为相对路径:
{ "scripts": { "build": "tsc && tsc-alias" } }
编译后的dist目录代码可以直接用Node原生运行,不需要额外loader。
内容的提问来源于stack exchange,提问作者rjurado01
相关产品推荐
相关产品推荐

