composer-php - composer require 如何解析项目中已有的依赖包?
问题描述
当使用composer require
将新包添加到现有项目时,composer 如何协调作为现有项目和新需要的包的依赖项的包的版本?
假设我有一个由包 A 组成的项目,并且包 A 依赖于包 B,版本约束为 ~1.0。在安装时,包 B 的当前版本是 1.1,所以这就是安装并写入锁定文件的内容。
然后稍后我想将包 C 添加到我的项目中。包 C 也依赖于包 B,但版本约束 >=1.0。在添加包 C 时,包 B 的最新版本是 1.2。
当我做 acomposer require C/C
时,包 B 会发生什么?根据原始安装和锁定文件,B 会保持在 1.1 吗?或者B会更新到最新版本(1.2)吗?
再次考虑上述情况,但唯一的区别是包 C 需要版本约束为 >1.1.3 的包 B。这次会有什么行为?composer会拒绝安装新的包C,因为依赖B的版本约束会与锁文件冲突吗?还是 composer 会将包 B 更新到最新版本(1.2)?
解决方案
我现在已经成功地测试了我上面描述的两种场景,作曲家的行为实际上相当不错。
如果您将包添加到现有项目(具有现有锁定文件)composer require <vendor>/<package>
,即使更新版本已发布,composer 也会维护锁定文件中列出的任何依赖项的锁定版本。所以在我上面的例子中,包 B 保持在 1.1 版本,因为这是在锁定文件中定义的。
如果,当您需要一个新包时,该包具有当前安装的该依赖项的版本无法满足的依赖项约束,即使该依赖项的较新版本与原始 composer.json 兼容,则 composer 给出以下错误:
Your requirements could not be resolved to an installable set of packages.
Problem 1
Can only install one of: vendor/b[v1.2, v1.1].
vendor/c v1.1 requires vendor/b ~1.2 -> satisfiable by vendor/b[v1.2].
Installation request for vendor/c ^1.1 -> satisfiable by vendor/c[v1.1].
Installation request for vendor/b (locked at v1.1, required as ~1.0) -> satisfiable by vendor/b[v1.1].
我认为关键位在哪里locked at v1.1
。
正如@Adam 所建议的那样,执行 acomposer require
似乎隐含地执行composer update
a ,但此更新似乎受到现有 composer.lock 文件的限制。composer require <vendor>/<package>
只做 a和 acomposer require <vendor>/<package> --no-update
后跟 a是有区别的composer update
。在 arequire --no-update
后跟 an的情况下update
,行为会有所不同,所有包都是从头开始解析的(没有锁定文件的引用),并且安装了最新版本的包。
以上所有内容均针对 composer 1.10 进行了测试。由于结果似乎合理且经过深思熟虑,我没有理由认为它会在 2.x 中发生变化,但我没有对此进行测试。
推荐阅读
- swagger - Grape Swagger 不显示示例参数
- python-3.x - 有没有一种 Pythonic 方法可以将一个字典映射到另一个字典?
- javascript - 用于生成树的 Javascript 递归函数 async-await
- python-3.x - Autopep8 可以在语法中支持 `source python django` 吗?
- opencv - 将turtle和opencv视频窗口拼接在一起
- c# - 使用 Gmail OAuth2 C# 发送邮件
- php - 如何让 Browser-Sync 在 Gulp 4 中提供 PHP 文件
- c# - 使用 Xamarin.Forms.Map 未显示标签和引脚
- c# - Nuget 管理器不使用包管理器从 Internet 安装包
- sql - 递归 CTE 填充多个季度的最新可用数据?