ERESOLVE 是 npm 7 之后默认开启 peer dependency 严格解析后抛出的依赖树求解失败,既不是网络问题,也不是权限问题,所以换源、清缓存、重装 node 这类动作通常无效。先读错误末尾那几行,判断是「两个包的版本范围真的凑不到一起」,还是「锁文件/package.json 里自己把版本钉死了」,再决定是升依赖还是临时放宽解析。
ERESOLVE 的排查点在错误文本本身:终端最后几行会指出哪个包要求了哪个 peer 范围、当前已安装的是什么版本。先确认 npm 版本(7 以上才有严格 peer 检查)、是 install 还是 ci、是否已有 legacy-peer-deps 配置,再用 npm ls 和 npm view 核对可用版本。能通过升级或降级对端包解决时优先改版本;--legacy-peer-deps 只作为安装阶段的放宽手段,它不修复运行时不兼容,写进 .npmrc 会影响整个团队和 CI,需要同步说明。
先确认当前场景和目标
这个问题成立的前提是:npm 版本在 7 及以上(用 npm -v 确认),报错发生在 npm install、npm i <包名> 或 npm ci 阶段,并且错误里出现 ERESOLVE 字样。如果 npm 还是 6,不会有严格 peer 检查,看到的往往是别的问题。
动手前先把这几项信息记下来,后面的判断全部依赖它们:

- npm 与 node 版本;
npm -v、node -v。 - 失败的是
npm install还是npm ci。后者对 lockfile 要求严格,报错含义不同。 - 项目根目录的
.npmrc里是否已经有legacy-peer-deps=true或force=true,以及 CI 配置里是否加了这些参数。 package-lock.json是否在版本控制里、最近是否被人改过或删过。- 依赖来自公共源还是私有源/镜像,私有源对某些新版本可能有同步延迟。
判断条件也在这里分开:错误里出现 Could not resolve dependency 并跟着 peer <包名>@<范围> from <上层包>@<版本>,说明是 peer 冲突;出现 No matching version found 或 404,更可能是版本写错或源上没有这个包,那属于另一类问题,不要用后文的放宽参数去硬解。
按这个顺序处理
按下面的顺序走,每一步都可能直接把问题消掉,不要一上来就加参数。终端里的报错通常是这种结构(示意,包名和版本以你自己的输出为准):

npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! Found: <包名>@<当前已安装版本>
npm ERR! Could not resolve dependency:
npm ERR! peer <包名>@"<要求范围>" from <上层包>@<版本>
- 定位冲突双方。从报错里抄出两个包名和它们各自要求的版本范围,再对照
package.json,看是不是自己把其中一方钉成了旧版本。 - 查真实可用版本。用下面的命令看已装版本、可安装版本和依赖来源,判断是否存在一个能同时满足两边的版本组合。
- 改版本而不是改参数。如果能找到兼容组合,升级报错里提到的那个上层包,或者把自己的直接依赖调到兼容范围,然后重新安装。这是唯一算「修好」的路径。
- 版本确实无解时,安装阶段放宽。使用
npm install --legacy-peer-deps,它会让 npm 跳过 peer 的自动安装与冲突校验,按旧行为装包。适合场景是:上游包尚未跟进、你只需要先把工程跑起来。 --force放在最后。它会在冲突时强行继续,可能覆盖 lockfile 里的已有条目,只在明确知道装上去的是什么版本、并且准备事后验证时使用。- 决定是否固化。如果团队确定要长期用放宽方式,把
legacy-peer-deps=true写进项目级.npmrc,并在 README 或提交说明里写清原因;不打算长期用时,不要写进 CI。
# 看当前装了什么版本、被谁依赖(较新版本 npm 提供 explain,老版本用 ls 代替)
npm ls <包名>
npm explain <包名>
# 看源上有哪些版本可装
npm view <包名> versions --json
# 安装阶段放宽 peer 校验
npm install --legacy-peer-deps
改完后怎么验证
装完不等于解决,要确认依赖树里没有残留的冲突标记:
- 再跑一次
npm ls <包名>,查看该包及其依赖分支下是否还有invalid或UNMET PEER DEPENDENCY标记。 - 执行
npm ls --all通读一遍输出,重点是上述两类标记;输出很长时可以重定向到文件再搜索。 - 在确认
package-lock.json已提交或已备份的前提下,删掉node_modules重新安装一次,看能否从零复现成功,而不是靠本地残留状态通过。 - 用
npm ci走一遍,验证 lockfile 与package.json一致;如果 CI 里用的是npm ci,本地这一步不通过,CI 大概率也过不了。 - 跑项目的构建和测试,尤其是用到出问题那个包的地方。peer 校验通过只说明依赖树自洽,不代表运行时行为正确。
预期信号是:安装无 ERESOLVE 报错、npm ls 无 invalid/UNMET 标记、npm ci 成功、构建与相关测试通过。四项里缺哪项,就说明放宽参数掩盖了还没解决的问题。
容易忽略的边界
- 放宽不等于兼容。
--legacy-peer-deps只是跳过校验,装上两个真实不兼容的版本,运行时报错可能推迟到构建或页面加载阶段才出现,排查成本更高。它属于止血措施,不是修复。 - lockfile 会记住这个参数。npm 会在
package-lock.json里记录生成时使用的解析模式,其他人用普通npm install时可能重新报错。团队要么统一配置,要么统一不加。 - 写进
.npmrc的影响面是全体。它对新加入的人、CI 流水线、以及未来迁移到 pnpm 或 yarn 时都可能有不同表现,需要在提交说明里写清生效范围。 - 源和镜像的同步延迟。私有源或镜像上暂时没有某个版本时,
npm view返回的版本列表可能不完整,这时改版本范围并不能解决问题,应先确认源上的实际内容。 - 不要把 engines 报错当成 ERESOLVE。node 版本不满足
engines时的提示文本不同,处理方式也不同,不要用同一套参数硬解。 - 回退方式。动手前先把
package.json和package-lock.json提交或备份;放宽参数后如果构建或运行异常,直接回退这两个文件并删除node_modules,回到干净状态重新判断,不要在已污染的依赖树上继续叠加改动。