使用ts-jest时import.meta.dirname和import.meta.filename始终为undefined的问题排查
我明白你把TypeScript项目从CommonJS迁移到ESM时遇到的这个棘手问题——在ts-node里正常可用的import.meta.dirname和import.meta.filename,切换到ts-jest运行测试时就变成了undefined,这种不一致性确实让人摸不着头脑。结合你的配置和遇到的场景,我来帮你梳理下原因和解决办法:
核心原因:ts-jest当前的ESM处理未适配这两个属性
首先可以明确的是:这不是你漏了配置,而是ts-jest目前的ESM转译逻辑中,并没有默认注入import.meta.dirname和import.meta.filename。
这两个属性是Node.js 20.11.0版本才正式稳定支持的ESM新增属性,而ts-jest的transformer在处理ESM测试文件时,暂时还没有适配注入这两个属性的逻辑——即使你已经正确开启了useESM: true和module: nodenext配置,官方示例中也存在同样的情况,进一步说明这是ts-jest当前的功能缺口,而非你的配置错误。
你的配置验证:没问题
先帮你确认下你的配置都是正确的,排除配置遗漏的可能:
tsconfig.json中module和moduleResolution设为nodenext,符合ESM项目的要求jest.config.ts中开启了useESM: true,添加了extensionsToTreatAsEsm,指定了正确的tsconfig路径,这些都是ESM测试所需的正确配置
可行的临时解决办法
在ts-jest修复这个问题之前,你可以用fileURLToPath和Node.js的URL API来模拟这两个属性,因为你提到import.meta.url是可用的:
封装工具函数避免重复代码
可以把这个逻辑封装成一个工具函数,在测试文件中复用:
import { fileURLToPath } from 'url'; import { dirname } from 'path'; // 获取当前文件的__dirname export const getCurrentDirname = (metaUrl: string) => { const currentFilename = fileURLToPath(metaUrl); return dirname(currentFilename); }; // 获取当前文件的__filename export const getCurrentFilename = (metaUrl: string) => { return fileURLToPath(metaUrl); };
在测试文件中使用
// 比如你的location.ts里可以改成 import { getCurrentDirname } from './utils'; export const getPath = () => { return getCurrentDirname(import.meta.url); };
这个方案在ts-jest环境下是完全可行的,不会影响功能。
长期方案:提交issue反馈
既然官方示例中也存在同样的问题,这说明这是ts-jest的一个未实现特性,你可以去ts-jest的GitHub仓库提交issue,说明以下信息:
- 你的Node.js版本、ts-jest版本、TypeScript版本
- 你的
tsconfig.json和jest.config.ts配置 - 描述ts-node中正常但ts-jest中
import.meta.dirname/filename为undefined的现象 - 附上最小可复现的测试代码
这能帮助ts-jest的开发团队更快地适配这个Node.js ESM的新特性。
内容来源于stack exchange

