什么是包管理器?

Avatar of Josh Collinsworth
Josh Collinsworth

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 $200 免费信用额度!

如果您正在记分,那么到目前为止,在本 npm 指南中,我们已经对 npm 是什么有了基本的了解——值得注意的是,它代表 Node 包管理器。在此过程中,我们讨论了命令行的重要性以及它如何在 npm 中使用。

我们还专门研究了 npm 中的“n”——Node——并了解到 Node 很像我们在浏览器中运行的网站上编写的 JavaScript 代码。实际上,Node **就是** JavaScript;它只是在浏览器之外运行,并且能够做一些与基于浏览器的内容不同的操作。

指南章节

  1. 本指南适合谁?
  2. “npm”到底是什么意思?
  3. 什么是命令行?
  4. 什么是 Node?
  5. 什么是包管理器? (您现在所处的位置!)
  6. 如何安装 npm?
  7. 如何安装 npm 包?
  8. 什么是 npm 命令?
  9. 如何安装现有 npm 项目?

我们所说的“包”

现在让我们将注意力转向 npm 中的最后两个字母,即“包管理器”部分。为了充分理解 npm 是什么,我们需要知道包管理器是什么。因此,自然而然地,为了理解,我们需要知道“包”到底是什么。

”是一个涵盖所有外部代码文件的通用术语,您可以将它们拉入项目并在某种程度上使用它们。也许您以前在项目中使用过 jQueryBootstrapAxios。这些都是包的常见示例。

我们称它们为“包”,因为它们被“打包”并随时可以被使用。一些语言称它们为其他名称(例如,Ruby 称它们为“gem”),但概念相同。为了避免过度简化,是您没有编写但从某些公共来源获取的代码,以在您的项目中使用。 您知道的,第三方代码。

或者,如果您更喜欢音乐模仿来作为记忆辅助工具

🎵 当您选择代码时
🎵 它不是您的,但您正在使用它
🎵 那就是包
🎵 当它是您安装的东西时
🎵 您导入并调用它,
🎵 那就是包

包通常也被称为“依赖项”,因为您编写的代码**依赖于**它们的存在。例如,使用 jQuery 的$ 编写的代码,如果 jQuery 本身没有加载,将无法正常工作。(出于这个原因,包管理器有时也被称为“依赖项管理器”。)

包的大小可以不同,具体取决于它们包含的代码量。一个包可能执行一项巨大的操作,从而改变您编写整个项目的方式(例如,一个完整的框架),或者它可能执行一项非常小的、专注的操作,您只需在需要的地方添加即可(例如,一个小部件或一个针对特定任务的辅助程序)。

不使用包管理器使用包

最有可能的是,如果您以前使用过包,您只是在 HTML 中使用一个脚本标签应用它,该标签从一个外部 URL 拉取(理想情况下,来自 CDN)。以下是如何在网站的 HTML 中包含 jQuery

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

另一种方法是下载包的副本,将其添加到项目的文件中,并链接到它,如下所示

<script src="/jquery.min.js"></script>

包管理器解决的问题

这些方法多年来一直运行良好。很简单。很干净。一般来说,它可以让你在包方面“设置好就不用管了”。那么为什么还需要其他东西呢?

您可以想象,拥有汽车对于那些可以方便地使用公共交通工具的人,或者那些不需要长途旅行的人来说可能没有吸引力。(我保证,这将与包管理器讨论联系起来。请耐心等待。)

如果您能方便地使用高效的公共交通工具,那么支付高价购买一辆大型机器,而且您必须将其存储在某个地方,定期清洁、维护和填充昂贵的燃料,从您的角度来看可能不会有什么优势。在这种特定情况下,好处微乎其微;而成本相对来说是压倒性的。处于这种假设情况中的人甚至可能会想知道为什么有人想要汽车!

我提出这个类比是因为,当**它解决的是您没有的问题**时,学习一项新技术可能非常困难,就像购买汽车可能无法解决您已经拥有的交通问题一样。这可能看起来像是一项巨大的、不必要的开支。

那么,包管理器解决的是扩展和处理问题。在脚本标签中简单地链接到一个包可以很好地工作,只要

  • 您拥有的项目数量是可以管理的;
  • 在项目中工作的人员数量是可以管理的;
  • 需要对包进行的更新数量是可以管理的;并且,最重要的是,
  • 项目中使用的所有包都是客户端(浏览器)JavaScript 或 CSS。

最后一个是棘手的,因为如果您只在浏览器中运行程序,就无法使用大量的工具(稍后会详细介绍)。

如果您确实符合所有这些条件,那么您可能永远不会超出这种方法的限制。您的开发方法可能看起来像这样

A black and white line illustration showing the diagram of packages with a package manager. A cloud labelled packages is followed by three files, HTML, CSS, and JavaScript, which are followed by the browser.

但是,即使在这种情况下,当您有多个<script> 标签,每个标签都链接到特定版本的某个脚本或库时,唯一查看您正在使用哪些包以及它们是否最新的方法是手动打开 HTML 并查看代码。

这本身并不是什么大问题,但随着项目规模和范围的扩大,这个问题会呈指数级增长。您可能能够手动跟踪几个包,但当我们谈论数百个——如果不是数千个——包时,您怎么可能做到呢?即使您能够手动跟踪这些包,仍然会带来人为错误的风险。

HTML 不应该成为项目中使用的所有包的真相来源。 除了混淆关注点之外,它还在尝试合并团队成员之间不相关的作品时,可能会引发冲突。

所有这些都很重要,但它们只是更大问题中的一小部分。请理解,客户端 JavaScript 可能永远不会是您想要包含在项目中的唯一类型的包,即使现在是这样——而这才是事情真正开始崩溃的地方。

许多生产应用程序使用以下工具和包的某种组合,如果不是全部的话

  • Sass(使编写 CSS 更容易)
  • PostCSS(增强 CSS 以实现最大效率和兼容性)
  • Babel(将较新的 JavaScript 转换为在较旧的浏览器中运行)
  • TypeScript(为 JavaScript 添加类型检查)
  • 由开发服务器提供的热模块重载,该服务器自动刷新浏览器以显示您的更改
  • 用于代码捆绑、缩小和/或连接的额外实用程序
  • 自动图像压缩
  • 测试库
  • 代码风格检查器

所有这些听起来都很棒——确实是这样的!——但请注意,您现在有多个依赖项,它们不仅不存在于您的脚本标签中,而且在您的项目中根本没有被记录下来!任何人——包括您未来的自己——都无法知道使用了哪些工具,或者需要哪些工具来使这个项目运行。

即使您可以确切地知道项目需要什么,您仍然需要自己去寻找、下载和安装所有这些包……手动。根据项目的不同,这很容易成为一项需要花费一整天甚至更长时间的任务。

所有这一切意味着您的工作流程现在看起来更像这样

A black and white line illustration showing the diagram of packages without a package manager. A group that consists of templates, Sass, and TypeScript or followed by static HTML, CSS, and JavaScript files, which are followed by a group that contains PostCSS and Babel, which is followed by a build tool, which is followed by two forks, one the dev server preview and the other the production browser.
再次强调,所有这些都很不错。这个工具链意味着发送到浏览器的代码是经过高度优化的——但它也是额外的开销和复杂性。

无论上述所有工具多么方便,您仍然需要管理它们。依赖项也是项目,它们会发布更新以修复错误并引入新功能。因此,简单地在 HTML 中粘贴一个指向 CDN 上的包的脚本标签,然后就万事大吉是不现实的。您必须确保每个东西都已安装并正常工作,不仅在您的机器上,而且在每个协作者的机器上也是如此。

包管理器存在是为了使项目的包——或依赖项——可管理,方法是知道安装了什么,什么可以更新,以及一个包是否可能与另一个包产生冲突。包管理器的妙处在于,它可以直接从命令行完成所有这些操作,而且工作量很少。

许多包管理器,特别是 npm,还提供了额外的功能,打开了更多可能性,让开发更高效。但管理包是其主要吸引力。

也有一些包管理器不是 npm

这部分与 npm 本身关系不大,但为了完整起见,我还是要提到 npm 不是唯一一个 JavaScript 包管理器。例如,你可能会在代码示例中看到 Yarn。Yarn 和 npm 的工作方式非常相似,二者之间的大量互操作性是特意内置的。

有些人更喜欢一种包管理器而不是另一种。我个人认为,npm 和 Yarn 之间的差异最初更为明显,但现在两者之间越来越相似。

你可能会看到代码示例(包括 CSS-Tricks 文章中的一些示例)同时引用 yarnnpm。这是为了让读者知道两种方法都可以,而不是需要同时使用它们。

Yarn 和 npm 的语法在某些时候有所不同,但在只存在一个的时候,通常将命令或项目从一个转换为另一个是微不足道的。在功能上,你使用哪个几乎无关紧要(如果确实无关紧要的话)——当然,除了所有在同一个项目上合作的人都需要使用同一个包管理器以确保兼容性和一致性。

虽然 npm 和 Yarn 占开发人员使用的大多数包管理器的绝大多数,但 另一个名为 PnPm 的包管理器实际上就是 npm,但性能更高、效率更高。缺点是,PnPm 在某些情况下需要更多的技术知识,因此它更像是一个高级选项。

Three examples of installing Vite in terminal via command line. First is npm, then Yarn, then PNPM.
不同包管理器之间的语法差异通常很小。(来源:Vite

是什么让 npm 成为“标准”包管理器

再说一次,我之所以提到其他包管理器,是为了说明 npm 不是唯一存在的包管理器——但它通常是标准。

是什么让它成为包管理器中的“标准”?其他语言,包括 Ruby 和 PHP,多年来都拥有包管理器;JavaScript 在 npm 出现之前确实没有好的包管理器。

npm 最初是一个独立的开源项目,但在 2020 年被微软收购。它实际上包含两个部分:实际的包管理器本身;以及包注册表,这是一个不断增长的列表,包含了 近 200 万个 可供安装的包。

你可以将 npm 视为任何你想在前端或 Node 基于项目中使用的应用程序商店。找到你想要的,并通过命令行将其安装到你的系统中。当发布新版本时,你可能需要更新该包,或者如果项目不再依赖于该包,则完全删除它。

关于 npx 的说明

你可能还会看到 npx 命令。 npx 实际上是 npm 的一部分,但通过在命令中使用 npx 而不是 npm,你可以执行包的代码 而无需 永久 安装它。NPX 只安装它需要的东西,运行它,然后丢弃它。

这很有帮助,例如,如果你想要运行一个安装程序脚本。与其下载安装程序,然后运行它,npx 让你直接运行安装程序,之后不会在你的机器上留下任何东西。它就像一个收拾干净的客人。

另一个很酷的例子:如果你想编译项目的 Sass 文件一次,而不必费心完全安装 Sass,你可以运行 npx sass(以及必要的输入和输出参数)。这在大多数情况下可能不切实际,但如果你只是需要偶尔进行快速一次性编译,npx 将是一个方便的方法,因为它意味着需要更新和维护的已安装包更少。

下一步

好了,这就是我们所说的包管理器的含义。在 npm 的情况下,它专门用于安装和管理 Node 包,这些工具有助于向项目添加功能,添加方便的开发便利性……或以上所有功能!

接下来,我们将迈出使用 npm 的第一步。为此,我们需要将它安装到我们的系统中。这是本 npm 全面指南中的下一步。