如何在TypeScript ESM项目中使@/别名生效?
问题描述
我用以下命令以ESM模式运行TypeScript脚本:
ts-node --esm -r tsconfig-paths/register -T src/server/api/jobs/index.ts
但无法处理import '@/server/init.ts'这类导入,报错:
CustomError: Cannot find package '@/server' imported from /Users/me/Sites/myapp/src/server/api/jobs/index.ts
已尝试的操作:
- 在
tsconfig.json中配置路径别名:"paths": { "@/*": ["src/*"] }, - 修改
package.json的name字段为"@/server"
文件夹结构:
/myapp package.json tsconfig.json /src /server /api /jobs index.ts
当前tsconfig.json配置:
{ "compilerOptions": { "allowSyntheticDefaultImports": true, "allowImportingTsExtensions": true, "allowJs": true, "baseUrl": "./src", "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "incremental": true, "isolatedModules": true, "jsx": "preserve", "lib": ["dom", "dom.iterable", "ES5"], "module": "ESNext", "moduleResolution": "NodeNext", "noEmit": true, "noUncheckedIndexedAccess": true, "pretty": true, "resolveJsonModule": true, "rootDir": ".", "skipLibCheck": true, "strict": true, "target": "ESNext", "types": ["node"], "paths": { "@/*": ["src/*"] }, "plugins": [ { "name": "next" } ] }, "include": [ ".eslintrc.cjs", "next-env.d.ts", "**/*.ts", "*.js", "**/*.js", "**/*.tsx", "**/*.cjs", "**/*.mjs", ".next/types/**/*.ts", "./src/*", "src/*" ], "exclude": ["node_modules"] // "ts-node": { // "esm": true, // "experimentalSpecifierResolution": "node", // "require": ["tsconfig-paths/register"] // } }
解决方案
1. 修正路径别名映射
你的baseUrl已设为./src,但paths里的@/*映射到src/*会导致路径重复(比如@/server/init.ts会被解析成src/src/server/init.ts),修改paths配置:
"paths": { "@/*": ["*"] }
这样@/server/init.ts会正确映射到src/server/init.ts。
2. 替换ESM兼容的路径加载器
tsconfig-paths/register对ESM模式支持不佳,改用tsconfig-paths/esm-loader,同时启用ts-node的ESM配置:
取消注释tsconfig.json中的ts-node部分并修改:
"ts-node": { "esm": true, "experimentalSpecifierResolution": "node", "loader": "tsconfig-paths/esm-loader" }
3. 调整运行命令
移除-r tsconfig-paths/register,改用加载器参数,最终命令:
ts-node --esm -T --loader tsconfig-paths/esm-loader src/server/api/jobs/index.ts
4. 还原package.json的name字段
将name改回正常项目名称(比如"name": "myapp"),之前设置的@/server会让Node误以为是npm包,导致解析错误。
5. 验证文件路径
确保import '@/server/init.ts'对应的src/server/init.ts文件存在,且文件名大小写与导入语句一致。
内容的提问来源于stack exchange,提问作者Garrett
相关产品推荐
相关产品推荐

