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

如何阻止Yarn 3(Berry)安装相同版本包的重复副本?

问题

使用Yarn 3(Berry)时,遇到相同版本的包被安装多份的问题。由于涉及有状态模块,可能在一个副本初始化状态后,Node从另一个副本读取值,导致异常。

示例场景:
包C包含需要单例的有状态模块,依赖关系如下:

A/package.json

{
  "version": "1.0.0",
  "name": "A",
  "dependencies": {
    "C": "1.0.0"
  }
}

B/package.json

{
  "version": "1.0.0",
  "name": "B",
  "dependencies": {
    "C": "1.0.0"
  }
}

项目根目录package.json

{
  "version": "1.0.0",
  "name": "project",
  "dependencies": {
    "A": "1.0.0",
    "B": "1.0.0",
    "C": "1.0.0"
  }
}

执行yarn install后,node_modules结构如下:

node_modules/
  - A
    - node_modules
      - C
        - package.json (v1.0.0)
        - <pkg code>
  - B
    - node_modules
      - C
        - package.json (v1.0.0)
        - <pkg code>
  - C
    - package.json (v1.0.0)
    - <pkg code>

已尝试用Yarn的resolutions字段强制C包解析为同一版本,也执行过yarn dedupe,但该命令仅对不同版本的包生效。需要让C仅在顶层node_modules中安装。

解决方案

1. 用packageExtensions强制依赖指向顶层包

在项目根目录的package.json中添加packageExtensions配置,修改A、B对C的依赖路径,让它们直接引用顶层的C包:

{
  "packageManager": "yarn@3.x.x",
  "dependencies": {
    "A": "1.0.0",
    "B": "1.0.0",
    "C": "1.0.0"
  },
  "packageExtensions": {
    "A@*": {
      "dependencies": {
        "C": "link:../C"
      }
    },
    "B@*": {
      "dependencies": {
        "C": "link:../C"
      }
    }
  }
}

配置完成后重新执行yarn install,A和B会直接使用顶层的C包,不会再安装私有副本。

2. 启用全局硬链接模式

在项目的.yarnrc.yml文件中设置:

nmMode: hardlinks-global

该模式会将所有同版本的包硬链接到全局缓存的同一个实例,虽然node_modules目录结构可能不变,但实际文件是共享的,状态会保持一致。

3. 用指定策略执行dedupe

尝试使用highest策略执行dedupe,强制将同版本依赖提升到最高层级:

yarn dedupe --strategy highest

这个命令会尝试把A、B下的C包都提升到顶层node_modules中。

4. 修改依赖包的依赖类型(临时方案)

如果是私有包或可修改的包,将A、B中C的依赖从dependencies改为peerDependencies:

// A/package.json
{
  "version": "1.0.0",
  "name": "A",
  "peerDependencies": {
    "C": "1.0.0"
  }
}

这样A、B不会自行安装C,而是依赖顶层项目提供的版本,需确保顶层已安装C。

内容的提问来源于stack exchange,提问作者Colin Harrison

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:25:17