Monorepo中Peer依赖判定及Yarn 2开发环境安装方法
我正在将仓库从旧版本Lerna升级至现代化构建工具,开发过程中遇到了问题。我们的地图覆盖组件需配合Mapbox或react-map-gl(React适配库)使用,此前这些库被设为peer依赖,因需与消费者提供的地图协同工作。升级至Yarn 2后,开发环境未安装peer依赖,导致项目无法构建,TypeScript报错无法找到对应包,node_modules中也无相关包。
报错信息如下:
src/index.tsx(1,30): error TS2307: Cannot find module 'mapbox-gl' or its corresponding type declarations.
src/index.tsx(4,39): error TS2307: Cannot find module 'react-map-gl' or its corresponding type declarations.
src/route-layers.ts(2,30): error TS2307: Cannot find module 'mapbox-gl' or its corresponding type declarations.
src/util.ts(1,24): error TS2307: Cannot find module 'mapbox-gl' or its corresponding type declarations.
咨询问题:
- Monorepo中哪些依赖应设为peer依赖而非常规依赖?
- 如何配置Yarn 2使其在开发环境安装peer依赖?
1. Monorepo中peer依赖的适用场景
- 核心框架/适配类依赖:如果你的包是基于外部核心框架(如React)或工具库(如mapbox-gl、react-map-gl)开发的组件/插件,且需要和消费者项目中已安装的同版本库协同工作,避免版本冲突,就应该设为peer依赖。比如UI组件库依赖React、地图组件依赖mapbox-gl这类场景。
- 版本敏感的协作依赖:当你的包功能依赖特定版本范围的外部库,且必须由消费者提供该库才能正常运行时,适合设为peer依赖。比如你的地图覆盖组件需要调用mapbox-gl的特定API,必须和消费者使用的版本兼容。
- 大体积冗余规避依赖:如果某个依赖体积较大,且消费者大概率已经安装(如React、lodash),设为peer依赖可以减少node_modules的冗余,降低整体安装体积。
注意:Monorepo内部包之间的依赖,若只是内部协作而非对外发布的组件,通常不需要设为peer依赖,直接用常规依赖即可。
2. Yarn 2配置开发环境安装peer依赖
Yarn 2默认不会自动安装peer依赖,可通过以下方式解决:
方式一:通过packageExtensions自动安装
在项目根目录的.yarnrc.yml中添加配置:
packageExtensions: "你的子包名称@*": peerDependenciesMeta: mapbox-gl: optional: false react-map-gl: optional: false dependencies: mapbox-gl: "^指定版本范围" # 替换为你需要的版本,比如^2.15.0 react-map-gl: "^指定版本范围" # 替换为你需要的版本,比如^7.1.0
替换你的子包名称为Monorepo中对应包的名称,配置后Yarn会在开发阶段自动安装这些peer依赖。
方式二:手动安装为根目录开发依赖
在Monorepo根目录执行命令,直接将peer依赖安装为开发依赖,同时安装TypeScript类型声明包解决类型报错:
yarn add --dev mapbox-gl react-map-gl @types/mapbox-gl @types/react-map-gl
额外:TypeScript路径补全配置
如果TypeScript仍有找不到模块的报错,可在子包的tsconfig.json中添加路径映射:
{ "compilerOptions": { "paths": { "mapbox-gl": ["../node_modules/mapbox-gl"], "react-map-gl": ["../node_modules/react-map-gl"] } } }
内容的提问来源于stack exchange,提问作者danielhep

