You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何删除package-lock.json和node_modules可解决React升级peer依赖冲突

React 17升级18时react-side-effect peer依赖冲突问题

问题背景

新加入项目后负责将React从17版本升级至18版本,执行npm install react@latest react-dom@latest升级react、react-dom及部分关联依赖后,出现若干依赖相关警告。多数警告可通过升级对应依赖包直接解决,但遇到了如下无法直接处理的警告:

npm WARN Conflicting peer dependency: react@17.0.2
npm WARN node_modules/react
npm WARN   peer react@"^16.3.0 || ^17.0.0" from react-side-effect@2.1.1
npm WARN   node_modules/react-helmet/node_modules/react-side-effect
npm WARN     react-side-effect@"^2.1.0" from react-helmet@6.1.0
npm WARN     node_modules/react-helmet

排查后发现,存在一个第三方自定义包将react@^17.0.2、react-dom@^17.0.2声明为普通依赖,导致依赖树中存在React 17.0.2版本的安装记录,对应声明如下:
依赖React 17.0.2的自定义包声明

"<CUSTOM PACKAGE MADE BY SOMEONE ELSE>": {
      "version": "0.3.0",
      "resolved": <内部包资源地址>,
      "integrity": "sha1-Ah72HLxApcdcSPGRIE/L7wjy8Ec=",
      "dependencies": {
        <CUSTOM PACKAGE MADE THE SAME PERSON 2>: "^0.1.6",
        "react": "^17.0.2",
        "react-dom": "^17.0.2",
        "react-scripts": "5.0.0"
      }
    },

实际安装的React 17.0.2依赖记录

"react": {
          "version": "17.0.2",
          "resolved": <npm公共包资源地址>,
          "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
          "requires": {
            "loose-envify": "^1.1.0",
            "object-assign": "^4.1.1"
          }

附加疑问

  • package-lock.json中同时存在两个版本的React是否会引发运行问题?
  • 这类场景下React本应被声明为peer依赖的判断是否正确?

排查过程

最初以为需要等待react-helmet适配React 18才能完成升级,但同事反馈其他同样使用react-helmet的项目已经成功升级至React 18,未出现同类警告。对照实验结果如下:

  • 仅删除package-lock.json后执行npm install,仍会出现相同警告
  • 同时删除package-lock.json和node_modules目录后重新执行安装,警告完全消失
    核心疑问:要求React 17.0.2的依赖包本身并未做任何修改,为何依赖冲突会被自动解决?

备注

已知react-helmet目前已停止维护,后续会替换为其他方案,该点不在本次问题的讨论范围内。

问题解答

关于peer依赖声明的判断

你的判断完全正确。所有面向React生态开发的组件、插件类包,都必须将react、react-dom声明为peerDependencies,而非普通dependencies。这类包本身不应该内置独立的React副本,必须复用宿主项目安装的React版本,否则必然会出现多副本React的问题,你遇到的这个第三方自定义包属于错误的依赖声明写法。

关于多版本React共存的运行风险

一定会引发运行问题。React内部依赖全局状态实现调度、上下文共享机制,同一应用运行两个React副本时,会出现Hooks调用报错(典型如Invalid hook call)、上下文丢失、事件调度异常等问题,且这类问题隐蔽性强,排查成本极高。

关于删除node_modules后警告消失的原因

这是npm v7+版本依赖提升(Hoist)机制的正常表现:

  • 仅删除package-lock.json时,node_modules目录下之前安装的嵌套React 17副本不会被清理,npm重新生成依赖树时会优先复用已存在的嵌套包,react-helmet所在的依赖链还是会匹配到这个17版本的React,因此会持续触发peer依赖警告。
  • 同时删除package-lock.json和node_modules目录后,npm会从零构建依赖树,优先将符合版本范围的包向顶层提升。此时项目顶层已经安装React 18,npm会判断react-side-effect声明的peer依赖范围^16.3.0 || ^17.0.0虽然未明确包含18,但实际运行兼容(react-helmet不依赖React 18的专属API,在18版本下可正常运行),因此不会额外安装React 17副本,直接将顶层的React 18共享给所有依赖链使用,警告自然消失。

注意:这种警告消失只是npm安装过程中未触发严格peer校验的结果,并非真正解决了依赖范围不匹配的问题。如果npm开启了严格peer模式(npm v7+默认开启),后续安装新依赖时很可能复现该警告。根治方案有两种:一是联系自定义包的维护者,将react、react-dom从普通dependencies移至peerDependencies;二是在项目package.json中添加overrides字段,强制所有依赖链复用项目顶层安装的React版本。

内容的提问来源于stack exchange,提问作者Fluous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 12:18:23