14

概括

我最近与我的一个应用程序所依赖的框架的创建者进行了对话。在那次谈话中,他顺便提到,如果我将他的框架与我的应用程序捆绑在一起,并向最终用户交付一个我知道与我的代码一致的版本,这将使我的生活更简单。直觉上,我一直试图避免这样做,事实上,我一直在努力分割自己的代码,以便在不占用整个项目的情况下重新分配部分代码(即使任何人都很少有机会重用任何代码)它)。然而,在考虑了一段时间之后,我无法想出一个特别好的理由来这样做。事实上,现在我已经考虑过了,我看到了一个非常有说服力的案例来捆绑我所有较小的依赖项。我已经列出了利弊清单,我希望有人能指出我遗漏的任何东西。

优点

  • 版本的一致性意味着更容易测试和故障排除。
  • 应用程序可能会覆盖更广泛的受众,因为要安装的组件似乎更少。
  • 对依赖项的小调整可以更容易地在下游进行并与应用程序一起交付,而不是等待它们渗透到上游代码库中。

缺点

  • 包含依赖项的更复杂的打包过程。
  • 用户最终可能会在他们的机器上获得多个依赖项副本。
  • 根据 bortzmeyer 的回应,无法升级单个组件存在潜在的安全问题。

笔记

作为参考,我的应用程序是用 Python 编写的,并且我引用的依赖项是“轻量级”的,我的意思是很小且不常用。(所以它们并不存在于所有机器上,甚至不存在于所有存储库中。)当我说“打包”我的应用程序时,我的意思是在我自己的源代码树下分发,而不是使用驻留在我的包内的脚本安装,所以会有不可能有冲突的版本。我也仅在 Linux 上进行开发,因此无需担心 Windows 安装问题。

话虽如此,我也有兴趣听到关于更广泛(与语言无关)打包依赖问题的任何想法。是我遗漏了什么,还是我只是想多了一个简单的决定?

附录 1

值得一提的是,我对下游打包者的需求也相当敏感。我希望尽可能简单地将应用程序包装在特定于发行版的 Deb 或 RPM 中。

4

8 回答 8

10

我赞成捆绑依赖关系,如果使用系统进行自动依赖关系解析(即 setuptools)是不可行的,并且如果你可以做到这一点而不会引入版本冲突。您仍然需要考虑您的应用程序和您的受众;认真的开发人员或爱好者更有可能希望使用特定(最新)版本的依赖项。捆绑东西可能对他们来说很烦人,因为这不是他们所期望的。

但是,特别是对于应用程序的最终用户,我严重怀疑大多数人是否喜欢搜索依赖项。就复制副本而言,我宁愿多花 10 毫秒下载一些额外的千字节,或者在额外兆的磁盘空间上花费一分钱,而不是花 10 多分钟在网站上搜索(可能会下降) )、下载、安装(如果版本不兼容可能会失败)等。

我不在乎我的磁盘上有多少个库副本,只要它们不妨碍彼此。磁盘空间非常非常便宜。

于 2009-02-28T18:03:58.683 回答
3

你不能只依赖这些依赖项的某个版本吗?例如,在带有setuptools的 Python 中,您可以指定它需要的确切版本,甚至可以给出一些条件,例如 <= > 等。这当然仅适用于 Python 和特定的包管理器,但我个人总是首先尝试不要捆绑所有内容。通过将其作为 Python Egg 发布,您还将自动安装所有依赖项。

您当然也可以使用双向策略来为您自己的包提供仅包含依赖项链接的包,但仍以某些安装程序(如时尚)提供完整的设置。但即便如此(在 python 的情况下)我还是建议简单地将鸡蛋与它捆绑在一起。

有关鸡蛋的一些介绍,请参阅我的这篇文章

当然,这是 Python 特有的,但我认为其他语言可能有类似的打包工具。

于 2009-02-28T17:24:01.713 回答
3

如果您为最终用户生产软件,目标是让客户使用您的软件。任何阻碍都会适得其反。如果他们必须自己下载依赖项,他们可能会决定避免使用您的软件。您无法控制库是否向后兼容,并且您不希望您的软件因为用户更新了他们的系统而停止工作。同样,您不希望客户使用旧库安装旧版本的软件并让系统的其余部分中断。

这意味着捆绑通常是要走的路。如果您可以确保您的软件在不捆绑依赖项的情况下顺利安装,而且工作量更少,那么这可能是一个更好的选择。这是关于什么让您的客户满意。

于 2009-03-02T20:20:52.503 回答
3

在将库/框架/等与应用程序捆绑在一起的缺点中似乎忘记了一个重要的点:安全更新。

大多数 Web 框架都充满了安全漏洞,需要经常打补丁。无论如何,任何库都可能因安全漏洞而不得不在某一天或另一天升级。

如果您不捆绑,系统管理员将只升级库的一份副本并重新启动依赖的应用程序。

如果你捆绑,系统管理员可能甚至不知道他们必须升级一些东西。

So, the issue with bundling is not the disk space, it's the risk of letting old and dangerous copies around.

于 2009-03-04T09:32:22.560 回答
2

对于 Linux,甚至不要考虑捆绑。你并不比包管理器或打包者聪明,而且每个发行版都采用自己的方式——如果你试图按照自己的方式行事,他们不会高兴的。充其量,他们不会费心打包你的应用程序,这不是很好。

请记住,在 Linux 中,会自动为您引入依赖项。这不是让用户得到它们的问题。它已经为你完成了。

对于 Windows,请随意捆绑,您自己在那里。

于 2009-03-02T20:05:06.987 回答
1

只是我的经验,持保留态度。

我对我编写的几个开源库的偏好是尽可能地独立于其他库。原因是,我不仅要与我的其他库一起分发,而且我还必须更新我的应用程序以实现兼容性,因为其他库也已更新。

从我使用的其他带有“通用”库依赖项的库中,我最终总是需要在我的系统上安装多个版本的通用库。我使用的小众库的相对更新速度并没有那么快,而普通库的更新频率更高。版本控制地狱。

但这是笼统地说。如果我现在可以通过合并依赖项来帮助我的项目和用户,我一直在关注该决定的下游和后期影响。如果我可以管理它,我可以自信地包含依赖项。

与往常一样,您的里程可能会有所不同。

于 2009-02-28T17:16:29.093 回答
1

我总是包含我的 Web 应用程序的所有依赖项。这不仅使安装更简单,而且即使系统上的其他组件升级,应用程序也能保持稳定并按照您期望的方式工作。

于 2009-02-28T20:14:12.613 回答
1

当心再现经典的 Windows DLL 地狱。一定要尽量减少依赖的数量:理想情况下,只依赖于你的语言及其框架,如果可以的话,别无其他。

毕竟,保留硬盘空间已不再是目标,因此用户不必关心拥有多个副本。此外,除非您的用户数量很少,否则请务必自行承担打包的责任,而不是要求他们获取所有依赖项!

于 2009-02-28T20:19:48.217 回答