Rush Monorepo下同版本react-redux依赖重复问题如何解决
问题根因
Rush 底层默认使用 pnpm 做依赖安装,.pnpm路径下带随机哈希后缀的文件夹是 pnpm 虚拟存储的标准目录结构,目录名的哈希值由依赖自身版本 + 该依赖所有 peerDependencies 的实际解析结果共同计算生成,并非Rush主动生成了多份副本。
出现同版本react-redux生成两份独立副本的核心原因,是两个项目下react-redux的peer依赖解析结果不一致:
- react-redux 本身将
react、redux声明为peer依赖,只要项目A和项目B中,react或redux的解析实例存在差异(哪怕版本号一致,只要被判定为不同的模块实例),pnpm就会为react-redux计算出不同的哈希值,生成独立的安装目录 - 如果内部包(比如项目A)将react-redux写入
dependencies而非peerDependencies,pnpm会默认给这个包单独安装一份react-redux私有副本,不会和项目B的依赖共享 - 若仓库存在历史锁文件残留、间接依赖引入了不同版本范围的react-redux且未做全局对齐,也会触发多副本生成
这种多副本会直接导致react-redux的Context对象不唯一:不同副本的react-redux会生成独立的Context实例,项目B的Provider用的是一份实例的Context,项目A调用hooks时读取的是另一份实例的Context,自然会出现上下文不匹配的报错。
修复方案
按以下步骤操作即可强制全仓库react-redux及关联单例依赖指向同一份副本:
- 开启全局版本一致性校验
打开仓库根目录的rush.json,将ensureConsistentVersions字段设置为true,强制所有内部包声明的公共依赖版本不能出现冲突。 - 配置全局优先版本,强制对齐单例依赖
打开common/config/rush/common-versions.json,在preferredVersions字段中声明所有需要保持单例的关联依赖版本,强制全仓库(包括间接依赖)的这类依赖都解析到指定版本:
其中{ "preferredVersions": { "react": "18.2.0", "react-dom": "18.2.0", "redux": "4.2.1", "react-redux": "8.1.2" }, "pnpmOverrides": { "react-redux": "8.1.2" } }pnpmOverrides会强制所有依赖(不管是直接依赖还是间接依赖)引用的react-redux都指向指定版本,从根源避免版本偏差。 - 调整内部包的依赖声明
所有导出react-redux相关逻辑的内部包(比如项目A),必须将react、react-dom、redux、react-redux从dependencies移到peerDependencies中声明,不要将这类单例依赖作为私有依赖安装。 - 清理缓存重装依赖
依次执行以下命令清理历史缓存并重新安装依赖:
安装完成后可以去rush purge rush installcommon/temp/node_modules/.pnpm目录检索,确认react-redux只存在一个对应版本的目录即可。
内容的提问来源于stack exchange,提问作者Matthew Winfield
相关产品推荐
相关产品推荐

