包管理器与依赖管理工具

对于初学者来说,“包管理器”、“依赖管理”、“构建工具”等概念是令人困惑且容易混淆的。并且,实际上很多工具本就“身兼多职”,也没有明确的角色区分,这进一步导致了这些概念上的混乱。在这一小节,我首先介绍什么是包管理器与依赖管理工具。

我们常说的“包管理器”,可能指系统上的软件包管理器,例如 Ubuntu 的 apt、CentOS 的 yum 与 ArchLinux 的 pacman,也可能指编程语言中的库管理器,通常是第三方库,比如 Python 自带的 Pip、JavaScript 生态中的 npm、Java 生态中的 Maven 等。对于后者,通常支持从网络中(一般是某个仓库网站,比如 Python 的 PyPI、Maven 的 MVN Repository 等)直接安装第三方库到本地。这样就可以免于繁琐的、在网络上寻找他人写好的库并费劲周折安装到你自己电脑上的麻烦。

还有一种被我称作“依赖管理”的工具,为一个个具体的代码项目工作,管理一个项目中所有的库,或者叫做“依赖”。这主要是由于不同的项目往往使用不同的编程语言版本甚至不同的第三方库版本,并且有独立的环境配置,如果让电脑上的所有项目都使用全局安装的库,就很容易出现不兼容问题,甚至因为编程语言版本不对而压根跑不起来。因此,通常的做法是为每一个项目单独管理一份环境,也就是“依赖管理”。实际上,大多数包管理器具有依赖管理的功能,比如 Maven、npm 这些工具天生就是“身兼数职”的工具,本就是为管理具体的某一项目而设计的,至于全局库的管理,反倒是顺带的。甚至,其实 Python 自带的 Pip 也有一定的“依赖管理”能力,Pip 可以通过建立一个虚拟环境为某个具体的项目安装特定版本的第三方库。只是 Pip 自身的依赖管理能力比较羸弱,存在很大缺陷,并且很难使用不同版本的 Python,因此出现了 Conda、Poetry 等解决方案提供更现代化的依赖管理能力。

需要注意的是,实际上关于这些工具的归类,一直没有一个明确的说法,这里将这些工具称作“包管理器”或“依赖管理工具”只是我个人的一种归类。包括下面提到的“打包工具”也是如此。

下面是一些编程语言中常见的包管理器/依赖管理工具。

  • Python - Pip / Conda | Poetry

  • Java - Maven / Gradle / Ant / Eclipse

  • C++ - vcpkg

  • C# - NuGet

  • JavaScript - npm / Yarn / pnpm

  • Ruby - RubyGems | Bundler

  • Go - Go Package

  • Rust - Cargo

Last updated