如何使用 Composer 中的 replace 属性?

本文详细阐述和解释 composer.json 文件中简单但非常重要的属性 replace 属性。

Composer 网站上的 官方 解释很简短,并没有真正解释它的用法。

让我们试着把它分解成一个个细节,这样我们就能深入的了解。官方文件说:

列出被此包替换的包。这样,您就可以派生一个包,并使用其自己的版本号以不同的名称发布它,而需要原始包的包可以继续使用您的派生,因为它会替换原始包。

注意「this」 这个词。这意味着在库中定义它时,该包将替换您在其上指定的任何包。如果您已经 fork 了一个库并且想要始终使用 fork,这可能会很有用。为了更好地理解这一点。让我们举个例子

  • 我有一个名为 「My App」的应用程序
  • 「My App」 需要两个软件包作为依赖,即 「original/library」 和 「other/package」
  • 「other/package」 依赖于「original/library」
  • 「original/library」的维护者不再更新它,并且上面有很多错误。
  • 您想解决 「original/library」上的问题,但他们不接受您的请求请求
  • 您在名为 「yourfork/library」的包中 fork 了「original/library」
  • 您在「My App」 项目中指定使用「yourfork/library」

如下图所示

Replace - New Page

现在的问题是,「other/package」 依赖于「original/library」。结果导致你的应用中加载了两个副本!这并不好,因为有 bug 的包(「original/library」)仍处于加载状态,并且可能会对您的应用程序造成严重破坏。

需要做一些事情,以便每当需要使用「original/library」时,Composer 都知道应该用你的 fork 「yourfork/library」来「替换」它。

输入替换属性

要解决此问题,您需要在 「yourfork/library」中指定 replace 属性, 以便 Composer 知道,无论何时需要该软件包,它都可以替代 「original/library」。

Replace - New Page (1)

现在。即使您没有直接「告诉」「other/package」 停止使用「original/library」,Composer 也不会再加载「original/library」,因为你告诉他可以将其替换为「yourfork/library」。

明白了吗?

另一个角度:

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

方案示例:

  • 我有一个名为「My App」的应用程序
  • 「vendor/framework」 是一个很酷但很大的的框架
  • 您可以在项目中需要整个「vendor/framework」,或者只是你需要的单个组件
  • 在初始阶段,「My App」仅需要「vendor/component1」,因为我们说项目只需要这个功能
  • 后来,您决定使用完整框架
  • 现在,您的「My App」需要两个软件包作为依赖项,即「vendor/framework」和「vendor/component1」
  • 但是「vendor/component1」类已经存在于「vendor/framework」中
  • 这似乎是一个冗余的代码,容易发生冲突!

下图描述了这种情况:

Replace - framework - New Page

乍一想,你可能会认为您只需将我的「My App」删除对「vendor/component1」的依赖即可。但是问题是,在大多数情况下,用户不知道哪个组件已经存在于哪个软件包中!
即使你知道,每个软件包都有成千上万的依赖关系,手工跟踪它也是一场噩梦。

因此,必须有一种方法让 Composer 知道,以便当「vendor/component1」已经「包含」在「vendor/framework」包中时,它应该告诉你「vendor/component1」不再需要单独存在了。

这可以通过在「vendor/framework」中放置替换属性来实现

Replace - framework - New Page (1)

安全注意事项

不过,这种行为显然有不必要的副作用。因为如果你需要一个不存在的包,而替换程序用自己的Fork(Fork 上有恶意代码)替换它,那么你就注定要失败。

该问题的解释超出了本文的范围,但是 你必须对这一问题进行自我教育,这样才能防止有人在你的代码库中「注入」恶意代码。

你可以检查以下线程以更好地了解此安全隐患:

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://www.darwinbiler.com/how-does-the...

译文地址:https://learnku.com/laravel/t/55168

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 1
Marrigan

学习了 :+1: :+1:

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!