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

Turbo monorepo+pnpm多React版本共存:阻止根目录版本提升

问题描述

在Turbo monorepo环境下使用pnpm时,遇到React版本冲突问题:

  • apps/web 依赖 React 16,apps/widget 依赖 React 18
  • 两个版本的React均被pnpm提升至根目录node_modules中,导致依赖React 16的web项目错误加载React 18,触发报错:
TypeError: Cannot read properties of null (reading 'useRef')
              at Object.useRef (/Users/joe-doe/customer/node_modules/.pnpm/react@18.2.0/node_modules/react/cjs/react.development.js:1630:21)

项目目录结构:

.
└── customer
    ├── apps/
    │   ├── web
    │   │   └── package.json <-- 依赖React 16
    │   └── widget
    │       └── package.json <-- 依赖React 18
    ├── package.json <-- 仅包含TS、eslint等公共依赖
    └── node_modules
        └── .pnpm
            ├── ... 其他依赖
            ├── react@16.14.0
            └── react@18.2.0

当前.npmrc配置:

strict-peer-dependencies=false
auto-install-peers=false
resolution-mode=highest
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=@types*

已尝试的无效配置:

hoist-pattern[]=!react@18.2.0
hoist-pattern[]=!react
hoist-pattern[]=!*react*
public-hoist-pattern[]=!react@18.2.0
public-hoist-pattern[]=!react
public-hoist-pattern[]=!*react*
解决方案

1. 修正.npmrc配置,彻底排除React的hoist

将以下配置添加到根目录.npmrc中,禁止所有React相关包被提升到根node_modules:

# 禁止React及ReactDOM被提升
hoist-pattern[]=!*react*
hoist-pattern[]=!*react-dom*
public-hoist-pattern[]=!*react*
public-hoist-pattern[]=!*react-dom*

2. 移除resolution-mode=highest配置

该配置会让pnpm优先选择依赖的最高版本,可能导致子项目指定的低版本React被强制升级。删除后,pnpm会严格遵循子项目package.json中指定的版本。

3. 锁定子项目的React精确版本

在apps/web/package.json中明确指定React 16的精确版本:

{
  "dependencies": {
    "react": "16.14.0",
    "react-dom": "16.14.0"
  }
}

在apps/widget/package.json中明确指定React 18的精确版本:

{
  "dependencies": {
    "react": "18.2.0",
    "react-dom": "18.2.0"
  }
}

4. 清理缓存并重新安装依赖

执行以下命令彻底清理缓存、删除现有依赖后重新安装:

pnpm store prune
rm -rf node_modules
rm -rf apps/web/node_modules
rm -rf apps/widget/node_modules
pnpm install

5. 验证依赖解析

通过以下命令检查子项目的React版本是否符合预期:

# 检查web项目的React版本
pnpm --filter web list react
# 检查widget项目的React版本
pnpm --filter widget list react

完成以上步骤后,两个子项目将各自加载对应版本的React,版本冲突问题即可解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:08:37