peerDependencies 是什么?

6,690 阅读2分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

大型前端项目的管理大多采用多项目的管理方式,也就是大家经常讨论的 monorepo 模式。monorepo 模式允许在一个根工作空间里存在多个项目,这些项目拥有自己的package.json文件。可以单独进行依赖管理。这些 package.json 文件中常常能见到 peerDependencies 配置项,那么 peerDependencies 配置项的作用是什么呢?他是为了解决什么问题而出现的呢?

初识 peerDependencies

在看 element-plus 的源码中发现 package.json 文件中有 peerDependencies 的配置,看名字猜想 peerDependencies 的作用可能是每个子项目共同使用的依赖。element-plus 的多项目管理工具是 pnpm+pnpm workspace 。packages 文件下的每个文件夹都各是一个子项目。

 // 根目录下的 package.json
 "peerDependencies": {
    "vue": "^3.2.0"
  },
  "dependencies": {
    "@element-plus/components": "workspace:*",
   },
  "devDependencies": {
    "vue": "^3.2.37",
    "vue-router": "^4.0.16",
    "vue-tsc": "^0.38.2"
  },

components 子项目中的package.json:

{
  "name": "@element-plus/components",
  "description": "all components are settled here",
  "peerDependencies": {
    "vue": "^3.2.0"
  },
}

发现 devDependencies 配置项中已经安装了 vue ,那么开始猜测的可能就不对了。

作用

peer 依赖,也叫同等依赖,或者叫同伴依赖,用于指定当前包(也就是你所要开发的包)使用的这个依赖要兼容的宿主环境中这个依赖的版本。用于解决插件与所依赖包不一致的问题。

这句话有点绕口,带入到上面的例子中去就是,主工作空间本身依赖 vue,现在开发了一个 @element-plus/components 组件项目,components 项目也依赖vue,反过来主工作空间又依赖了components。

重点来了,在安装依赖的时候主 工作空间 既需要安装它本身的所需要的 vue 的版本,还需要安装 components 包所需要的 vue 版本,如果二者的 vue 版本不同,那么在一个项目中有多个不同的依赖项集合根据pnpm工作方式,pnpm 必须有几组不同的依赖项,就去硬链接几次。

但是如果有peer依赖的话,那么它可能就会有多组依赖项,就会为不同的 peer 依赖项创建不同的解析。详情:pnpm.io/zh/how-peer…

例如:

"peerDependencies": {
    "vue": "^3.2.0"
  },

它要求宿主环境安装 vue 3.x.x 的最新版本不能小于 3.2.0.

此时在主系统中生成的依赖图就是这样的:

.
├── element-plus
│   └── node_modules
│       ├── vue@3.2.0
│       └── @element-plus/components

总结

当你安装一个包时,其 dependencies 和 devDependencies 会被 npm 自动安装。 peerDependencies 不会被自动安装。

当一个依赖项 (例如vue) 被列在某个包 components 的 peerDependency 中时,它就不会被自动安装。取而代之的是,包含了 components 包的代码库 (element-plus) 则必须将对应的依赖项 ( vue ) 包含为其依赖。

文中有的地方可能理解不到位表述错误,恳请指出,不胜感激。