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

Monorepo中加载关联包时如何忽略开发依赖避免多lib实例?

问题:Monorepo插件共享依赖的单副本加载需求

我们维护着一个存储JavaScript库(下称lib)插件的Monorepo仓库,lib本身不属于该仓库,仓库通过Lerna管理。所有插件和lib一样均发布为NPM包,每个插件都将lib同时声明为peer依赖和dev依赖,部分插件还存在互相依赖的情况。

运行lerna bootstrap后,仓库的简化结构如下:

plugins/
├─┬ a/
│ ├── index.js
│ └─┬ node_modules/
│   ├─┬ lib/
│   │ └── (... 内容省略)
│   └─┬ @lib/
│     └── b@ -> ../../../b
└─┬ b/
  ├── index.js
  └─┬ node_modules/
    └─┬ lib/
      └── (... 内容省略)

注:相互依赖的插件由Lerna创建符号链接,每个插件因lib是dev依赖而拥有独立的lib副本。

plugins/a/index.js代码如下:

import * as lib from 'lib';
import * as b from 'b';

plugins/b/index.js仅包含:

import * as lib from 'lib';

由于lib内部维护着状态,加载plugins/a/index.js时,a和b会各自加载独立的lib副本,导致依赖两者共享同一内部状态的测试全部失败。

需要说明的是,NPM包用户不会遇到这个问题——因为lib是@lib/a和@lib/b的peer依赖,正常使用时用户只会安装一个lib副本。问题仅出现在本地开发/测试阶段:lib作为b的dev依赖被安装,且该副本会被优先加载。

是否有办法让b作为a的依赖被加载时,不使用自身dev依赖的lib副本,转而复用a的lib副本?

此前我们通过Webpack为每个测试套件构建独立包来规避这个问题,对应的webpack.config.js配置如下:

{
  resolve: {
    alias: {
      lib: path.resolve(fs.realpathSync(process.cwd()), 'node_modules/lib'),
    },
    // ... 其他配置
  }
  // ... 其他配置
}

该配置会强制所有import 'lib'的操作都加载当前测试插件(如plugins/a/node_modules/lib)的副本,但存在两个明显缺点:

  • 最紧急的问题:该配置会导致Webpack忽略lib的package.json中新增的exports字段,引发导入错误(尤其是子路径导出场景)。我尝试过设置alias: {lib: 'lib'},希望既能强制使用单一副本又不破坏常规Node模块解析规则,但没有效果。
  • 必须先打包代码和测试才能运行,速度远慢于直接在Node.js中执行测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:53:26