如何让ts-jest执行的测试使用指定项目目录的node_modules?
解决Jest+ts-jest下符号链接共享目录的模块解析问题
首先,你的问题核心在于:Jest默认不会跟随符号链接解析模块,而且当运行testC.ts时,TypeScript/ts-jest会以common目录本身作为解析根路径,而非它被软链接所在的项目(A或B)的根目录,导致找不到项目里的node_modules。下面是几个针对性的解决方案,按优先级排序:
方案1:自定义Jest解析器,强制模块解析基于项目根目录
你可以写一个简单的自定义resolver,让所有模块解析都基于当前执行测试的项目根目录(比如A或B的目录),而不是符号链接指向的实际common目录。
步骤1:创建自定义resolver文件
在项目A(或B)的根目录下创建jest-resolver.js:
const path = require('path'); const defaultResolver = require('jest-resolve/build/defaultResolver').default; module.exports = (request, options) => { // 如果是common目录里的文件,将解析根路径设置为当前项目根目录 if (options.path.includes(path.resolve(__dirname, 'common'))) { return defaultResolver(request, { ...options, rootDir: __dirname, moduleDirectories: [path.resolve(__dirname, 'node_modules')], }); } // 其他文件用默认解析逻辑 return defaultResolver(request, options); };
步骤2:修改jest.config.js的resolver配置
把原来的resolver: "jest-pnp-resolver"替换成自定义的resolver,同时补充关键路径配置:
module.exports = { // ...保留原有其他配置 resolver: './jest-resolver.js', // 调整moduleDirectories,确保优先使用项目的node_modules moduleDirectories: ['node_modules', __dirname], globals: { "ts-jest": { tsConfig: { baseUrl: __dirname, // 明确指向项目根目录 paths: { "common/*": ["./common/*"] // 对应软链接的路径映射 } } } }, // ...保留原有其他配置 };
方案2:使用环境变量动态适配多项目配置
如果你需要在A和B项目里共用同一个jest配置,可以通过环境变量传递当前项目根目录,动态配置路径参数:
修改jest.config.js:
const path = require('path'); const projectRoot = process.env.PROJECT_ROOT || __dirname; module.exports = { rootDir: projectRoot, roots: [path.resolve(projectRoot, '../common'), path.resolve(projectRoot, 'src')], // ...保留原有其他配置 moduleDirectories: [path.resolve(projectRoot, 'node_modules'), 'node_modules'], globals: { "ts-jest": { tsConfig: { baseUrl: projectRoot, paths: { "common/*": ["./common/*"] } } } }, // ...保留原有其他配置 };
运行测试时传递环境变量:
在项目A的根目录执行:
PROJECT_ROOT=/home/large-project/projects/A npx jest
在项目B的根目录执行:
PROJECT_ROOT=/home/large-project/projects/B npx jest
方案3:临时禁用Jest的符号链接隔离(快速验证用)
Jest有一个--no-symlinks参数,可以强制它解析符号链接的实际路径,不过这可能带来重复模块加载的风险,仅作为问题验证手段:
npx jest --no-symlinks
关键配置说明
- moduleDirectories:必须把项目的
node_modules放在最前面,确保解析器优先查找当前项目的依赖,而非common目录的上级目录。 - ts-jest的baseUrl:明确设置为项目根目录,让TypeScript的模块解析逻辑和Jest保持一致,避免路径不匹配。
- 自定义resolver:核心是拦截common目录下的文件解析请求,强制切换到项目根目录的上下文,确保依赖从项目的node_modules加载。
内容的提问来源于stack exchange,提问作者VitalyB
相关产品推荐
相关产品推荐

