认识package,你必须知道的Dependencies和peerDependencies的关系,应该用哪个?

在此之前我们需要知道,什么是依赖项?

依赖项是一个 npm 包,我们的包依赖于它才能运行。通常作为依赖项添加的一些流行包是 lodash、axios 和 moment。

场景

假设你正在创建一个 Vue 库,甚至只是一个导出某些函数的简单 JavaScript 文件。你的项目依赖于 npm 注册表中的包。这些包是项目的依赖项。你希望从项目创建自己的 npm 包。因此,你可以用 npm pack 从项目中生成 npm 包,还可以将其发布到 npm 仓库。

其他团队会将你的包作为依赖项添加到他们自己的项目中。我们在 package.json 中使用Dependencies和peerDependencies来告诉这些其他项目还需要添加哪些包才能使我们的包正常工作。

因此,在最基本的层面上,这就是Dependencies和peerDependencies的工作方式:

Dependencies

Dependencies(依赖项)列在项目中的 package.json 文件中。

如:

json 复制代码
"dependencies": {
    "lodash": "^4.17.11"
  }

当我们在 dependencies 中添加包时,我们的意愿是:

  1. 我的代码需要此包才能运行。
  2. 如果此包在我的node_modules目录中尚不存在,则自动添加它。
  3. 添加包的依赖项中列出的包。这些包称为传递依赖项。

Peer Dependencies (对等依赖关系)

Peer Dependencies :对等依赖项列在 package.json 文件中的peerDependencies里面。

如:

json 复制代码
"peerDependencies": {
  "@angular/core": "^7.0.0"
}

当在peerDependencies 里面添加包时, 我们的意愿是:

  1. 我的代码与此版本的包兼容。
  2. 如果此包已存在于node_modules中,则不执行任何操作。
  3. 如果此包在 node_modules 目录中尚不存在,或者它是错误的版本,请不要添加它。但是,向用户显示未找到它的警告。(npm警告,yarn直接报错终止下载)

那么,某个 npm 包应该进入 dependencies 还是进入 peerDependencies ,该怎么判断呢?

我们通过一个示例来更好的理解:

示例

首先,我们创建一个简单的测试项目:

shell 复制代码
mkdir conflict-test
cd conflict-test
npm init -y

然后,手动编辑package.json文件并添加了两个依赖项:

json 复制代码
"dependencies": {
  "todd-a": "^1.0.0",
  "todd-b": "^1.0.0"
}

这些 todd-a 和 todd-b 包也有其自己的依赖项:

todd-a

json 复制代码
"dependencies": {
  "lodash": "^4.17.11",
  "todd-child": "^1.0.0"
}

todd-b

json 复制代码
"dependencies": {
  "lodash": "^4.17.11",
  "todd-child": "^2.0.0"
}

在这里需要注意到的是, todd-a 和 todd-b 使用相同的版本 lodash 。但是,它们的 todd-child 存在版本冲突:

  • todd-a 使用 Todd-Child 版本 1.0.0
  • todd-b 使用 Todd-Child 版本 2.0.0

看看 npm 如何处理这个版本冲突。

在我的 conflict-test主项目中 ,我运行 npm install .正如我们所期望的那样,npm 将 todd-a 和 todd-b 包安装在我们的 node_modules 文件夹中。它还添加它们所依赖的包(传递依赖项)。因此,运行 npm install 后,我们查看node_modules文件夹。它看起来像这样:

powershell 复制代码
node_modules
├── lodash 4.17.11
├── todd-a 1.0.0
├── todd-b 1.0.0
│   └── node_modules
│       └── todd-child 2.0.0
└── todd-child 1.0.0

值得注意的是,我们的项目有一个 lodash 依赖项。但是,它有两个 todd-child 依赖项。并且注意, todd-b 获取自己的私有依赖项 todd-child 2.0.0 。

所以npm的冲突处理规则是:npm 通过添加冲突包的重复私有版本来处理版本冲突。

有时,拥有同一包的两个版本是可以的。但是,当同一代码库中有两个不同版本的包时,某些包会导致冲突。

例如,假设我们的组件库是使用 Vue2 创建的。当有人将其作为依赖项添加到他们的应用程序中时,我们不希望我们的npm包添加另一个完全不同的版本Vue,如Vue3

关键是:

我们不希望我们的库将另一个版本的包添加到node-modules中,因为该包可能与现有版本冲突并导致问题。

peerDependencies or dependencies?

因此,这给我们带来了依赖项的主要问题:

当我的包依赖于另一个包时,我应该把它放在 dependencies还是peerDependencies 中?

《准则》

当满足以下条件之一时,支持使用peerDependencies:

  • 拥有包的多个副本会导致冲突

  • 依赖项在您的界面中可见

  • 你希望开发人员自己决定要安装的版本

让我们以react-dom 为例 。显然,如果您正在创建一个 react 库,react-dom将成为库界面中非常明显的部分。因此,它属于 peerDependencies .

见react-dom官方的package.json:github.com/facebook/re...

更多示例:

但是,也许你的库在内部使用 day.js 来处理一些与时间相关的输入。day.js很可能不会暴露在你的 react 组件的界面中。因此,它属于 dependencies .

相关推荐
好开心3312 分钟前
axios的使用
开发语言·前端·javascript·前端框架·html
Domain-zhuo21 分钟前
Git常用命令
前端·git·gitee·github·gitea·gitcode
菜根Sec1 小时前
XSS跨站脚本攻击漏洞练习
前端·xss
m0_748257181 小时前
Spring Boot FileUpLoad and Interceptor(文件上传和拦截器,Web入门知识)
前端·spring boot·后端
桃园码工1 小时前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲2 小时前
2024不一样的VUE3期末考查
前端·javascript·程序员
Anlici2 小时前
three.js建立3D模型展示地球+高亮
前端·数据可视化·canvas
轻口味2 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami2 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
wakangda3 小时前
React Native 集成原生Android功能
javascript·react native·react.js