“替换"是如何实现的?与作曲家合作?如何实现、作曲家、quot

2023-09-06 16:34:04 作者:不愿面对现实的奶茶爱好者

那么replace"属性如何与作曲家?我已经阅读了作曲家文档,但仍然不明白.搜索更多信息并没有回答我的问题.

So how does the "replace" property work with composer? I have read the composer document but still not understand it. Searching for more info hasn't answered my questions.

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

When I look at the composer.json file on Laravel/Framework on github. I can't see how replace will work. Can someone explain to me how this works? And what the variable "self.version" will equal to?

推荐答案

Composer 文档提供了两个基本示例.我会尽力解释:

The Composer documentation gives two basic examples. I'll try to explain:

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

Lists packages that are replaced by this package. This allows you to fork a package, publish it under a different name with its own version numbers, while packages requiring the original package continue to work with your fork because it replaces the original package.

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

Suppose your software uses original/library and other/package, which itself also requires original/library.

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

Now you think that original/library needs to integrate a feature, but the maintainers won't let your suggestion happen in their package. You decide to fork that library under the name better/library, and tag a new release.

回到您的软件.当然它应该开始使用 better/library,所以你需要它,但是 other/package 仍然需要 original/library - 代码复制!你如何让其他包使用你的 better/library 而不是分叉它并且只更改 composer.json (你仍然与那个 original/library 兼容,所以它应该工作)?

Back to your software. Of course it should start using better/library, so you require that instead, but that other/package still requires the original/library - code duplication! How can you make that other package to use your better/library instead without also forking it and only changing the composer.json (you are still compatible to that original/library, so it should work)?

您将替换键添加到您的 composer.json:

You add a replace key to your composer.json:

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

现在 Composer 知道,在解决 other/包.

Now Composer knows that any package from your better/library is equally good as the original/library when it comes to resolving the dependencies of the other/package.

这对于包含子包的包也很有用,例如主 symfony/symfony 包包含所有 Symfony 组件,这些组件也可以作为单独的包使用.如果您需要主包,它将自动满足单个组件之一的任何要求,因为它会替换它们.

This is also useful for packages that contain sub-packages, for example the main symfony/symfony package contains all the Symfony Components which are also available as individual packages. If you require the main package it will automatically fulfill any requirement of one of the individual components, since it replaces them.

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

The same rules, a slightly different angle: Requiring components of a framework is a good approach for any other component that needs some feature. But if you require the full framework in your software, and another library, which subsequently also requires a component of that framework, the replace declaration of the framework allows Composer to not have to install that single component twice, because it is already included in the full framework.

注意:替换版本中的占位符通常不好

在我原来的回答中我建议:

In my original answer I suggested:

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

这会产生后果:Composer 现在会将您的库版本 1.0.0 视为与原始库的任何版本 1.x 一样好,即使他们修复了某些内容或添加了功能并在某天发布了版本 1.2.34.这也意味着,如果您的 other/package 某天得到更新并需要 original/library:^1.1,则 YOUR 库中的替换为仍然处于活动状态并声明它可以替换任何版本 1.*,即使您不更新内部的任何内容 - 它不能,如果您不做一些工作,您的旧代码将永远不会实现原始库的新功能,但替换说明正是如此.

This has consequences: Composer will now treat your library version 1.0.0 to be as good as ANY version 1.x of the original library, even if they fix stuff or add features and release version 1.2.34 some day. This also means that if your other/package some day gets an update and requires original/library:^1.1, the replacement in YOUR library is still active and states that it can replace ANY version 1.*, even without you updating anything inside - which it can not, your old code will never implement new features of the original library without you doing some work, but the replacement states exactly this.

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

So in essence: Avoid wildcard versions in the replacement version! If you use them, you make a statement about the future that you cannot know or predict (unless you can control original/library, but even then be very careful). Always use a specific version of the original/library that you know and can re-implement completely.