66

那么“替换”属性如何与作曲家一起使用?我已经阅读了作曲家文档,但仍然不明白。搜索更多信息并没有回答我的问题。

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

4

2 回答 2

104

Composer 文档提供了两个基本示例。我将尝试解释:

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

假设您的软件使用original/libraryand 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/libraryoriginal/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始终使用您知道并且可以完全重新实现的特定版本。

于 2013-09-19T21:17:33.623 回答
9

当您创建自己的包时,您可以在自己的包中定义composer.json它的类型,provide这基本上告诉Composer您的包已经安装,因此无需再次安装。

如果你使用replaceproperty,它告诉 Composer 你的包想用你自己的 fork 替换原来的包,所以其他包不需要安装它。

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

在这里更详细地解释了这一点:“替换”属性如何在 Composer 中工作?

Composer 中的“替换”属性如何工作 - 图

于 2017-12-12T14:48:44.810 回答