“替换”属性如何与作曲家一起使用?

问题描述 投票:40回答:2

那么“replace”属性如何与composer一起使用?我读过作曲家的文档,但仍然不理解。搜索更多信息没有回答我的问题。

当我在github上查看Laravel/Framework上的composer.json文件时。我看不出替换会如何工作。有人可以向我解释这是如何工作的吗?变量“self.version”将等于什么?

replace composer-php package-managers
2个回答
73
投票

Composer文档提供了两个基本示例。我会试着解释一下:

列出由此包替换的包。这允许您分叉一个包,使用其自己的版本号以不同的名称发布它,而需要原始包的包继续使用您的fork,因为它取代了原始包。

假设您的软件使用original/libraryother/package,它本身也需要original/library

现在你认为original/library需要集成一个功能,但维护者不会让你的建议在他们的包中发生。您决定以名称better/library分叉该库,并标记新版本。

回到你的软件。当然它应该开始使用better/library,所以你需要它,但other/package仍然需要original/library - 代码重复!你怎么能让其他包使用你的better/library而不用它也只是改变composer.json(你仍然兼容那个original/library,所以它应该工作)?

您为composer.json添加了替换键:

"replace": {
    "original/library":"1.0.2"
}

现在,Composer知道,当解决better/library的依赖关系时,来自original/library的任何包都和other/package一样好。

这对于包含子包的包也很有用,例如,主symfony / symfony包中包含所有Symfony组件,这些组件也可作为单独的包提供。如果您需要主包,它将自动满足其中一个组件的任何要求,因为它取代了它们。

相同的规则,略有不同的角度:对于需要某些功能的任何其他组件,需要框架的组件是一种很好的方法。但是如果您需要软件中的完整框架和另一个库(后来也需要该框架的组件),框架的replace声明允许Composer不必安装两次单个组件,因为它已经包含在完整的框架。

注意:替换版本中的占位符通常很糟糕

在我的原始答案中,我建议:

"replace": {
    "original/library":"1.*"
}

这会带来影响:Composer现在会将您的库版本1.0.0视为原始库的任何版本1.x,即使他们有一天修复内容或添加功能并发布版本1.2.34。这也意味着,如果你的other/package有一天得到更新并需要original/library:^1.1,你的库中的替换仍然是活动的并声明它可以替换任何版本的1.*,即使你没有更新任何内部 - 它不能,你的旧代码将如果没有你做一些工作,就永远不会实现原始库的新功能,但是替换就是这样。

所以本质上:在替换版本中避免使用通配符版本!如果你使用它们,你就未来做出一个你无法知道或预测的陈述(除非你能控制original/library,但即使这样也要非常小心)。始终使用您知道的特定版本的original/library,并且可以完全重新实现。


5
投票

当你创建自己的包时,你在composer.json中定义了什么类型的包provide它基本上告诉Composer你的包已经安装了它,所以不需要再次安装它。

如果您使用replace property,它会告诉Composer您的软件包想要用您自己的fork替换原始软件包,因此其他软件包不需要安装它。

例如,如果a/a包需要b/b并且你告诉替换b/b,它将不会在Composer install / update上下载。

这里有更详细的解释:How does the “replace” property work in Composer?

How does the “replace” property work in Composer - diagram

© www.soinside.com 2019 - 2024. All rights reserved.