yarn@3.0.1 PnP模式下加载运行时创建的依赖报错如何解决?
可行解决方案
按改造成本和适配性从高到低排序:
1. 提前声明本地链接依赖(最优方案)
直接在package.json的devDependencies中声明测试用的本地依赖,不需要运行时创建软链接,完全符合Yarn PnP的依赖管理规则:
{ "devDependencies": { "transport": "link:./test/fixtures/transport" } }
执行yarn install后,PnP会自动生成transport包的映射关系,不会再触发未声明依赖的报错,也不需要修改现有测试逻辑。
2. 动态注册PnP包映射
如果你的测试依赖内容是运行时动态生成、无法提前声明,可以调用Yarn暴露的PnP API手动添加包的映射规则,在创建软链接的代码后添加以下逻辑:
const pnp = require('pnpapi') const transportRoot = join(__dirname, 'fixtures', 'transport') const testDirPattern = new RegExp(join(__dirname, '.*')) pnp.registerPackageRequest( 'transport', { packageLocation: `${transportRoot}/`, packageDependencies: new Map() // 若transport有自身依赖可在此处补充 }, testDirPattern // 仅对测试目录下的请求生效 )
3. 单条加载逻辑绕过PnP
如果不想修改依赖配置和PnP规则,可直接通过绝对路径加载目标模块,或者创建原生require函数绕过PnP校验:
// 直接传入模块绝对路径,跳过包名解析 myMod({ load: join(__dirname, 'fixtures', 'transport') }) // 或者创建不受PnP管控的原生require函数 const nativeRequire = module.createRequire(join(__dirname, 'fixtures', 'transport')) const transport = nativeRequire('./index.js')
4. 单文件忽略PnP校验
如果要保留现有运行时软链接逻辑,可针对单个测试文件关闭PnP校验,不会影响其他文件的PnP规则:
在测试运行命令中临时设置环境变量:
YARN_PNP_IGNORE_PATTERNS=./test/transport.test.js yarn test
或者在测试文件开头添加PnP禁用注释:
/* pnp-disable */ const myMod = require('my-module') // 其余测试逻辑
内容的提问来源于stack exchange,提问作者Manuel Spigolon
相关产品推荐
相关产品推荐

