My Recipe Against Dependency Hell

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

你是否指定你的依赖项的确切版本?我的意思是,当你的软件包依赖于另一个软件包时,你是否在你的pom.xmlGruntfileGemfile或其他文件中写下它的版本,例如1.13.5还是只写1.+?我一直以为最好使用确切的版本号,以避免所谓的“依赖地狱”,而且我并不孤单。然而,很快我意识到动态版本(如1.+)更加灵活。就在几周前,我意识到这两种方法都不正确,然后找到了一个混合的方案。毫不奇怪,我又发现我并不孤单。

首先,让我解释一下固定依赖项的问题。

假设我创建了一个名为X的库,它依赖于一个日志记录工具,这是一个第三方库,不是我的。因此,我的库X有一个依赖项。日志记录库有一个版本号,例如1.13.5。我将这段文字放入X的pom.xml文件中:

许多固定依赖的支持者认为,坚持使用版本1.13.5而不是更灵活的动态版本1.13)(即任何1.13或更新的版本)非常重要。为什么呢?因为未来的版本可能会引入一些会破坏X的构建的内容。它们可能会更改接口,重命名类或方法,或删除我正在使用的某些内容。你永远不知道这个log-me库的作者可能会做什么。这就是为什么最好将自己与1.13.5硬编码并称之为一天的结束。

But.

如果库X被另一个库Y使用,并且库Y也依赖于log-me,但需要版本1.14.1,那将会出现冲突。库Y中会发生冲突:Maven(包管理器)无法决定使用哪个版本。必须以某种方式解决这个冲突。在Maven的情况下,可以解决,但在例如Rake的情况下,我不确定。

为了解决这个问题,库Y必须明确指定要使用的版本。但它不能确定1.14.1是否能正确地与库X配合使用。要确认这一点,需要由库X的作者进行测试。因此,库Y的创建者所能做的最好的办法就是尝试并希望一切顺利。对于其他构建工具(如Rake),作者将别无选择,只能要求库X的作者升级到1.14.1并发布新版本。然后,库Y将能够使用库X。

如果库X依赖于1.13,这个问题就不会存在。但如上所述,在那种情况下,它的作者将埋下一个定时炸弹——未来的某个版本肯定会破坏构建。

那么解决方案是什么呢?

这是我的建议:如果你信任库的作者,使用动态版本;如果你不信任,使用固定版本。

我的意思是,你是否相信他们足够专业,能够考虑向后兼容性并遵循语义化版本控制的原则?如果他们足够小心,不会删除或修改可能影响未来版本的内容,而不改变版本的主号码,那么你可以信任他们。如何知道谁值得信任?我除了我自己的库和一小部分我在GitHub上审查过并检查过其代码库质量的其他库之外,我不信任任何人。

当然,你不能完全信任任何人,但这是我目前对自己的公式。你可以在这个Gemfile中看到它是如何工作的。注意版本号。以~>>=开头的是动态版本,其他是固定版本。这是一种混合方法,但对我有效。

也许对你也有帮助。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 10:03

sixnines availability badge   GitHub stars