使用 Yarn workspaces/nohoist 时,如何控制 Yarn 为依赖项的 peerDependency 选择哪个版本?
How do I control which version Yarn chooses for a dependency's peerDependency when using Yarn workspaces/nohoist?
我有一个包含两个包的 Yarn 工作区,watermelon-web
和 watermelon-native
,它们使用最新版本的 react-redux
但不同版本的 react
。问题是我无法控制 react
Yarn 为 react-redux
.
的 peerDependency 选择哪个版本
工作区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"
。
我想要发生的事情: Yarn 安装后,watermelon-native/node_modules/react-redux/node_modules
不包含 react
。这样,当 react-redux
尝试在 运行 时导入 react
时,它将从 watermelon-native/node_modules
.
得到 react@16.8.3
实际发生了什么: Yarn 在 watermelon-native/node_modules/react-redux/node_modules
中安装 react@16.12.0
。当我 运行 watermelon-native
时,React 报告 "Invalid hook call" 因为 watermelon-native
使用 react@16.8.3
但 react-redux
使用 react@16.12.0
。 (两个包必须使用完全相同的 React 实例才能使 React 挂钩工作。)
如何让 Yarn 按照我想要的方式工作?
我已经尝试使用 Yarn selective dependency resolutions,也就是 package.json
中的 "resolutions" 元素,几乎以所有可能的方式,但 Yarn 的行为没有明显的变化。例如,我尝试添加
"resolutions": {
"**/watermelon-native/react-redux/react": "16.8.3"
}
到工作区package.json
。
两个简单的 "solutions" 是在我的所有包中使用相同的 React 版本(需要将 watermelon-web
降级到 16.8.3
)或放弃使用 Yarn 工作区。如果可能,我想避免这些缺点。
(注意:我的代码示例来自React Native开发,但问题本身仅适用于Yarn,与React无关。react
和react-redux
可以替换为任何其他具有足够相似依赖关系的包。)
我认为问题的答案只是“纱线不能那样工作”,至少目前是这样。
与此同时,我找到了一个简单的解决方法。由于从 watermelon-native/node_modules/react-redux/node_modules/react
中删除 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 magic 让他们的 React Native 应用程序与 yarn 工作区一起工作。所以也许这个解决方法还不错。
我有一个包含两个包的 Yarn 工作区,watermelon-web
和 watermelon-native
,它们使用最新版本的 react-redux
但不同版本的 react
。问题是我无法控制 react
Yarn 为 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"
。
我想要发生的事情: Yarn 安装后,watermelon-native/node_modules/react-redux/node_modules
不包含 react
。这样,当 react-redux
尝试在 运行 时导入 react
时,它将从 watermelon-native/node_modules
.
react@16.8.3
实际发生了什么: Yarn 在 watermelon-native/node_modules/react-redux/node_modules
中安装 react@16.12.0
。当我 运行 watermelon-native
时,React 报告 "Invalid hook call" 因为 watermelon-native
使用 react@16.8.3
但 react-redux
使用 react@16.12.0
。 (两个包必须使用完全相同的 React 实例才能使 React 挂钩工作。)
如何让 Yarn 按照我想要的方式工作?
我已经尝试使用 Yarn selective dependency resolutions,也就是 package.json
中的 "resolutions" 元素,几乎以所有可能的方式,但 Yarn 的行为没有明显的变化。例如,我尝试添加
"resolutions": {
"**/watermelon-native/react-redux/react": "16.8.3"
}
到工作区package.json
。
两个简单的 "solutions" 是在我的所有包中使用相同的 React 版本(需要将 watermelon-web
降级到 16.8.3
)或放弃使用 Yarn 工作区。如果可能,我想避免这些缺点。
(注意:我的代码示例来自React Native开发,但问题本身仅适用于Yarn,与React无关。react
和react-redux
可以替换为任何其他具有足够相似依赖关系的包。)
我认为问题的答案只是“纱线不能那样工作”,至少目前是这样。
与此同时,我找到了一个简单的解决方法。由于从 watermelon-native/node_modules/react-redux/node_modules/react
中删除 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 magic 让他们的 React Native 应用程序与 yarn 工作区一起工作。所以也许这个解决方法还不错。