我有一个包含两个软件包watermelon-web
和watermelon-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-redux
和exec.Command
可以被任何其他可替换的包替换具有足够相似的依赖关系。)
答案 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应用程序与纱线工作区一起使用。因此,也许这种解决方法还不错。