使用Yarn工作区/ nohoist时,如何控制Yarn选择哪个版本作为依赖项的peerDependency?

时间:2019-11-26 23:45:59

标签: react-native yarnpkg yarn-workspaces

我有一个包含两个软件包watermelon-webwatermelon-native的Yarn工作区,这两个软件包使用react-redux的最新版本,但使用react的不同版本。问题是我无法控制react peerDependency 的哪个版本的react-redux Yarn选择。

工作区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.3中获得watermelon-native/node_modules

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

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

我尝试过使用package.json中的Yarn selective dependency resolutions,也就是"resolutions": { "**/watermelon-native/react-redux/react": "16.8.3" } 中的“ resolutions”元素,但是Yarn的行为没有可观察到的变化。例如,我尝试添加

package.json

进入工作区watermelon-web

两个简单的“解决方案”是在我的所有软件包中使用相同的React版本(将需要将16.8.3降级为react)或放弃使用Yarn工作区。这些缺点都有我想避免的缺点。

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

1 个答案:

答案 0 :(得分:0)

认为,至少暂时来说,这个问题的答案是“纱线不能那样工作”。

同时,我找到了一个简单的解决方法。由于从react删除watermelon-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")

这确实很棘手,但是即使Expo项目也依靠postinstall magic来使他们的React Native应用程序与纱线工作区一起使用。因此,也许这种解决方法还不错。