npm install 突然卡在 ERESOLVE unable to resolve dependency tree,本质不是网络或缓存问题,而是两个包对同一个 peer 依赖(通常是 React、Vue、ESLint 这类”宿主包”)声明的版本区间互相打架。npm 7 起默认严格校验 peer 依赖,宁可报错拦你,也比 npm 6 时代默默装上、上线后崩了强。读懂那段报错里的四个关键值,十分钟就能理清。
ERESOLVE 到底在说什么
把下面这段报错拆开看,其实信息很全:
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error Found: react@19.1.0
npm error Could not resolve dependency:
npm error peer react@"^18.0.0" from some-library@4.2.0
四个关键值:Found 是 npm 当前选定的版本(react@19.1.0);Could not resolve dependency 指出是谁在要 peer;peer react@”^18.0.0″ 是它接受的区间;some-library@4.2.0 是冲突来源。结论通常二选一:要么把 some-library 升到支持 React 19 的版本,要么把 react 钉在 18.x。
四步理清冲突
别急着加 --legacy-peer-deps 糊弄过去,先用四条命令把依赖树看明白。下面是一套可复用的排查流程:
→
2 npm explain
→
3 npm view 查 peer
→
4 –dry-run 预览
# 看依赖树,depth 控制展开层级
npm ls react --depth=2
# 解释某个包为何存在、被谁引入
npm explain react
# 查目标包当前版本到底要什么 peer
npm view some-library@latest peerDependencies
三种解法,按代价排序
理清之后,按”代价从低到高”挑一个,别一上来就 –force:
| 方案 | 做法 | 代价 | 适合场景 |
|---|---|---|---|
| 升级兼容版本 | npm install some-library@latest |
低 | 对方已支持你的版本 |
| overrides 强制 | package.json 加 overrides | 中 | monorepo / 子依赖死活不升 |
| –legacy-peer-deps | npm install --legacy-peer-deps |
高,埋雷 | 临时本地验证 |
| –force | npm install --force |
最高,危险 | 几乎不要 |
重点提醒:--legacy-peer-deps 只是让 npm 跳过校验,并没有解决真实不兼容。别写进全局 .npmrc 然后忘掉——它会悄悄影响之后的每一次安装。
踩坑实录
升级 React 18→19 后,npm install 直接 ERESOLVE。我图快加了 --legacy-peer-deps 装上了,本地跑得好好的。两周后 CI 用 npm ci 重装,那个老图表库仍按 react@^17 解析,某组件调用了 React 19 才移除的旧 API,staging 渲染时直接白屏。根因就是:跳过校验 ≠ 解决不兼容,雷只是延后引爆。
monorepo 里用 overrides 一锤定音
多包仓库里子依赖死活不升级时,根 package.json 的 overrides 能强制统一版本:
{
"overrides": {
"some-library": {
"react": "19.1.0"
}
}
}
注意 workspaces 下根和子包的大版本要对齐(React 和 react-dom 要一起升),否则下次还会冒出新的 peer 冲突。改完记得重跑 npm install 让 lockfile 重新计算。
常见问题
–legacy-peer-deps 能长期用吗?
不能。它是迁移期的桥,不是修复。长期用它,等于把兼容性炸弹往后挪,哪天 runtime 才炸。
CI 装得上、本地装不上?
比对两边 node --version、npm --version、npm config get legacy-peer-deps 以及 package-lock.json 是否一致。CI 多跑 npm ci,会严格按 lockfile,本地却可能用了没提交的旧 node_modules。
npm ci 和 npm install 差在哪?
ci 严格按已提交的 lockfile 安装且不改写它;install 可能重算依赖图。所以”本地能装 CI 炸”多半是 lockfile 没提交或版本漂移。
如果你也在升级依赖时踩过 peer 冲突的坑,欢迎在 fenij.com 留言说说你的解法,一起把这套排查流程补全。