那么“replace”属性如何与composer一起使用?我读过作曲家的文档,但仍然不理解。搜索更多信息没有回答我的问题。
当我在github上查看Laravel/Framework上的composer.json文件时。我看不出替换会如何工作。有人可以向我解释这是如何工作的吗?变量“self.version”将等于什么?
Composer文档提供了两个基本示例。我会试着解释一下:
列出由此包替换的包。这允许您分叉一个包,使用其自己的版本号以不同的名称发布它,而需要原始包的包继续使用您的fork,因为它取代了原始包。
假设您的软件使用original/library
和other/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
,并且可以完全重新实现。
当你创建自己的包时,你在composer.json
中定义了什么类型的包provide
它基本上告诉Composer你的包已经安装了它,所以不需要再次安装它。
如果您使用replace
property,它会告诉Composer您的软件包想要用您自己的fork替换原始软件包,因此其他软件包不需要安装它。
例如,如果a/a
包需要b/b
并且你告诉替换b/b
,它将不会在Composer install
/ update
上下载。