我用的 yarn v4 版本,所以以下教程命令都基于yarn
这里假设我报错的库名字叫 XXXXXXXX,依赖他的库叫 AAAAAAAA
排查解决思路分析:
++首先查看一下 XXXXXXXX 的依赖关系,执行++
bash
yarn why XXXXXXXX
首先我们要知道 yarn 自动做了库的拆分,所以不同的库依赖不同的版本的某个库是互相隔离的,我们几乎在任何时间都不需要check这个问题,除了以下几种问题
如果看到类似的输出,比如一个库依赖项是 XXXXXXXX: ^0.0.1-beta.29,但他的 node_modules 下载的却是 [email protected]
perl
└─ AAAAAAAA@npm:0.0.1
└─XXXXXXXX@npm:0.0.1-local.8 (via npm:^0.0.1-bata.29)
那我们就先++看下是不是本地有这个 cache 缓存++
我们先看下项目里有没有 .yarn/cache 这个文件,如果有就查看是不是命中了缓存
如果没有这个目录,先查看 cache 目录在哪里
bash
yarn config get cacheFolder
知道了缓存的目录后,查看是否命中
bash
ls .yarn/cache | grep XXXXXXXX
我的输出如下
perl
XXXXXXXX-0.0.1-local.8-ddea0537de-10c0.zip
所以可以发现,我确实是因为命中了缓存才导致的问题,所以我们执行
bash
yarn cache clean
yarn install
之后我发现还是没有成功,于是检查一下 yarn.lock 文件是否有锁定的版本
bash
cat ./yarn.lock | grep XXXXXXXX
我这里输出如下,可以看到
perl
"XXXXXXXX": "npm:^0.0.1-bata.29"
"XXXXXXXX@npm:^0.0.1-bata.29":
resolution: "XXXXXXXX@npm:0.0.1-local.8"
于是我执行
bash
yarn cache clean
rm yarn.lock
yarn install
之后我发现还是没有解决该问题
那么几乎可以判断为,不是缓存问题,而是 yarn registry(包源)里这个版本就叫做 0.0.1-local.8
,并且它"伪装"为 ^0.0.1-bata.29
的合法候选项!或者说他还没有被注册到 yarn regitstry 里。
也就是说,Yarn 从 远程 registry(yarn私有源) 获取到了一个叫:[email protected] 的库
但它被误判为匹配:^0.0.1-beta.29
为什么 ^0.0.1-beta.29
能匹配 0.0.1-local.8
?
在 semver 标准里:
-
^0.0.1-beta.29
只允许 patch-level 的预发版本,如:-
0.0.1-beta.30
-
0.0.1-rc.1
-
-
但 如果 registry 中
0.0.1-local.8
是唯一匹配的预发版本,Yarn可能会选它,尽管它显然不是正式版本。
这说明你的环境中:
🧨
0.0.1-local.8
是注册在 yarn 或私有 registry 上的,并且是目前唯一可解的版本。
如何修复????
- 强制指定明确版本(不是 semver 范围)「我比较推荐这种写法」
修改 package.json, 增加resolutions
bash
"resolutions": {
"XXXXXXXX": "0.0.1-beta.29"
}
⚠️ 注意:必须是完整版本号,不要写 ^0.0.1-beta.29
,因为 Yarn 会再次去解析 semver 范围,从而回到 local.8
。
或者固定下载源
bash
"resolutions": {
"XXXXXXXX": "https://registry.npmjs.org/XXXXXXXX/-/XXXXXXXX-0.0.1-beta.29.tgz"
}
然后执行
bash
rm yarn.lock
yarn install
- 明确锁定版本来源(需要使用官方 npm 源)
你可以临时限制 registry,强制从 registry.npmjs.org
获取(防止从私有源或本地镜像拿到污染版本,比如你用的淘宝源):
在 .yarnrc.yml 中制定,yarn 一般用的自己的下载源 (https://registry.yarnpkg.com)因为yarn下载比较快,所以我不建议直接这样改
XML
npmRegistryServer: "https://registry.npmjs.org"
然后执行
bash
rm yarn.lock
yarn install
- 如果还是不是你想要的版本,我们需要排查一下可用版本是否并没有被发布
bash
yarn npm info XXXXXXXX --fields versions
如果没有 0.0.1-beta.29
,那你只能:
-
改用别的版本;
-
或让你团队发布一个新的版本(例如
0.0.1-beta.30
);
到此,我的问题解决,如果你还有其他问题,欢迎评论区留言提问