首页 > 解决方案 > 使用 Yarn 工作区/nohoist 时,如何控制 Yarn 为依赖项的 peerDependency 选择哪个版本?

问题描述

我有一个带有两个包的 Yarn 工作区watermelon-webwatermelon-native,它们使用最新版本react-redux但不同版本的react. 问题是我无法控制为.peerDependency选择哪个版本的reactYarn 。react-redux

工作区package.json

{
    "private": true,
    "workspaces": {
        "packages": [
            "watermelon-web",
            "watermelon-native"
        ],
        "nohoist": [            
            "**/watermelon-native/react-redux"
        ]
    }
}

(需要 nohoist 来防止运行时错误)

watermelon-web/package.json

{
  "name": "watermelon-web",
  "dependencies": {
    "react": "^16.12.0",
    "react-redux": "^7.1.3"
  }
}

watermelon-native/package.json

{
  "name": "watermelon-native",
  "dependencies": {
    "react": "16.8.3",
    "react-redux": "^7.1.3"
  }
}

同时,react-redux有一个 peerDependency "react": "^16.8.3"

我想要发生的事情:纱线安装后,watermelon-native/node_modules/react-redux/node_modules不包含react. 这样,当react-redux尝试react在运行时导入时,它会react@16.8.3watermelon-native/node_modules.

实际发生的情况:纱线安装react@16.12.0watermelon-native/node_modules/react-redux/node_modules. 当我运行时watermelon-native,React 报告“无效的钩子调用”,因为watermelon-native正在使用react@16.8.3react-redux正在使用react@16.12.0. (两个包必须使用完全相同的 React 实例才能使 React 挂钩工作。)

如何让 Yarn 以我想要的方式工作?

我已经尝试使用Yarn 选择性依赖解决方案,也就是 中的“解决方案”元素package.json,几乎所有可能的方式,但 Yarn 的行为没有明显的变化。例如,我尝试添加

"resolutions": {
    "**/watermelon-native/react-redux/react": "16.8.3"
}

到工作区package.json

两个简单的“解决方案”是在我的所有包中使用相同的 React 版本(需要降级watermelon-web16.8.3)或放弃使用 Yarn 工作区。这些中的每一个都有我想尽可能避免的缺点。

react(注意:我的代码示例来自 React Native 开发,但问题本身仅适用于 Yarn,与React 无关。react-redux可以替换为具有足够相似依赖关系的任何其他包。)

标签: react-nativeyarnpkgyarn-workspaces

解决方案


认为这个问题的答案只是“Yarn 不能那样工作”,至少目前是这样。

与此同时,我找到了一个简单的解决方法。由于reactwatermelon-native/node_modules/react-redux/node_modules/react解决问题中删除文件夹,我添加了一个postinstall脚本,react在每次安装后删除该文件夹。

我的 PowerShell 脚本(使用你喜欢的任何 shell)

function TryRemove-Path($path) {
    if(Test-Path $path) {
        Remove-Item -Recurse -Force $path
    }
}


TryRemove-Path("$PSScriptRoot/node_modules/react-redux/node_modules/react")

这很 hacky,但即使是 Expo 项目也依赖postinstall 魔法来让他们的 React Native 应用程序与 yarn 工作区一起工作。所以也许这个解决方法不是那么糟糕。


推荐阅读