那么“替换”属性如何与作曲家一起使用?我已经阅读了作曲家文档,但仍然不明白。搜索更多信息并没有回答我的问题。
当我在 github上查看 Laravel/Framework上的 composer.json 文件时。我看不到替换将如何工作。有人可以向我解释这是如何工作的吗?变量“self.version”将等于什么?
那么“替换”属性如何与作曲家一起使用?我已经阅读了作曲家文档,但仍然不明白。搜索更多信息并没有回答我的问题。
当我在 github上查看 Laravel/Framework上的 composer.json 文件时。我看不到替换将如何工作。有人可以向我解释这是如何工作的吗?变量“self.version”将等于什么?
Composer 文档提供了两个基本示例。我将尝试解释:
列出被此包替换的包。这允许你分叉一个包,以不同的名称和它自己的版本号发布它,而需要原始包的包继续使用你的分叉,因为它替换了原始包。
假设您的软件使用original/library
and other/package
,它本身也需要original/library
.
现在你认为original/library
需要集成一个特性,但维护者不会让你的建议出现在他们的包中。您决定在 name 下派生该库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
。
在这里更详细地解释了这一点:“替换”属性如何在 Composer 中工作?