「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
本文将比较Yarn与npm这两个最流行的包管理器。 分别探讨它们各自的优缺点,以帮助读者选择自己项目适合的工具。
基础知识
在以前,一个简单的文本编辑器足以让开发人员管理他们的大部分项目。 但之后,Web 发生了翻天覆地的变化。 如今,即使是一个相当简单的项目,也很常见有成百上千个脚本,具有复杂的嵌套依赖关系,如果没有某种自动化工具,这些脚本根本无法管理。 这就是包管理器发挥作用的地方。
包管理器是一种能够以多种方式管理项目依赖关系的工具,例如,在包管理器的帮助下,我们可以安装、卸载、更新和升级包,配置项目设置,运行脚本等。 所有繁重而乏味的工作都由包管理器完成,开发人员指关心有趣的部分——编码本身。
npm也就是Node Package Manager。 它于 2010 年发布,开启了Web开发的新时代。 在此之前,项目依赖项是手动下载和管理的。 npm 是将 Web 推向新高度的魔杖。
npm实际上涉及三个方面:
- 一个用于管理npm各方面体验的网站
- 用于访问庞大公共JavaScript包数据库的方式
- 用于通过终端与npm 交互的命令行界面 (CLI)
然而,大多时候我们提及npm 时,我们通常指的是最后一个——CLI 工具。 它作为默认包管理器,随Node安装同时安装。 这意味着我们安装了Node就可以立即使用npm。
Yarn就是Yet Another Resource Negotiator,由 Facebook 于 2016 年 10 月发布。 Yarn 的最初目标是解决npm 的缺点,例如性能和安全问题。 Yarn 很快被定位为安全、快速、可靠的 JavaScript 依赖管理工具。
但是 npm 团队吸取了教训,并通过实现缺失的功能迅速修复了npm的缺陷。
- 2010 年:npm 发布,支持 Node.js。
- 2016 年:发布yarn。 它显示出比 npm 更高的性能。 它还生成一个 yarn.lock 文件,使 repos的精确管理变得更加容易。
- 2017 年:npm 5 发布。 它提供了一个 package-lock.json 文件的自动生成来响应 yarn.lock。
- 2018 年:npm 6 发布,安全性更高。 现在 npm 在安装依赖项之前检查安全漏洞。
- 2020 年:Yarn 2 和 npm 7 发布。 这两个软件包都带有很棒的新功能。
- 2021 年:Yarn 3 发布并进行了各种改进。
如今,这两个包管理器在包管理竞赛中并驾齐驱,提供相似的特性和功能。 但是仍有一些差异有助于我们确定选择使用哪个。
1.Yarn vs npm: 安装方面的比较
1.1包管理器本身的安装
正如上面提到的, Node预装了 npm,所以不需要手动安装 npm。 相比之下,Yarn 需要显式安装。 首先,我们需要全局安装 Yarn:
npm install -g yarn
然后,我们可以在我们的项目中设置所需的版本,可以通过在项目的根目录中运行 yarn set version 命令来做到这一点:
yarn set version berry
berry是我们要设置的版本。如果想更新到最新版本,我们运行这个:
yarn set version latest
使用 Yarn,我们可以为每个项目使用不同的版本。
要对 npm 执行相同操作,我们需要安装 nvm。
1.2 安装项目依赖的比较
现在,让我们看看如何安装项目依赖项。
当我们运行 npm install 时,依赖项会依次安装,一个接一个。 终端中的输出日志信息丰富,但有点难以阅读。
要使用Yarn安装软件包,我们需要运行yarn命令。 Yarn 并行安装包,这也是它比 npm 更快的原因之一。 如果您使用的是Yarn1,您会看到 Yarn 输出日志是干净的简短的。 为了便于理解,它们以树的形式排列。 但这在版本 2 和 3 中发生了变化,日志不再那么直观和可读。
2.比较npm和Yarn命令
npm 和 Yarn 共享许多命令,但也有许多不同的命令。 让我们首先来看一些相同的命令:
npm init | yarn init:创建一个新包
npm run | yarn run:运行 package.json 中定义的脚本
npm test | yarn test:测试一个包裹
npm publish | publish:发布一个包
npm cache clean | yarn cache clean:从缓存文件夹中删除所有数据
这些相同的命令使两个管理器之间的切换变得容易,但有也有一些不同的命令:
npm install | yarn:安装依赖项
npm install package | yarn add package:安装一个包
npm install --save-dev package | yarn add - -dev package: 安装一个包作为开发依赖
npm uninstall package | yarn remove package:卸载一个包
npm uninstall --save-dev package | yarn remove package:卸载开发依赖包
npm update | yarn upgrade:更新依赖项
npm update package | yarn upgrade package:更新一个包
Yarn 也有一些独特的命令,它们没有 npm 等效项。 例如,why 命令显示需要包的原因:它可能是一个依赖项、一个本地模块或一个项目依赖项。
3.速度和性能
Yarn 或 npm安装包时,它们都会执行一系列任务。 在npm中,这些任务是按包顺序执行的,这意味着它会等待一个包完全安装,然后再继续下一个。 相比之下,Yarn 并行执行这些任务,从而提高了性能。
虽然两个管理器都提供缓存机制,但 Yarn 似乎做得更好一些。 通过实现零安装范式,它几乎可以立即安装软件包。它缓存每个包并将其保存在磁盘上,因此在此包的下一次安装中,甚至不需要互联网连接,因为该包是从磁盘离线安装的。
尽管 Yarn 有一些优势,但 Yarn 和 npm 在它们的最新版本中的速度相当。 所以我们不能在这里定义真正的赢家。
4.安全性比较
npm的主要被批评的之一就是安全性。 以前的 npm 版本有几个严重的安全漏洞。从版本 6 开始,npm 会在安装过程中审核软件包,并告诉我们是否发现了什么漏洞。 我们可以通过对已安装的软件包运行 npm audit 来手动执行此检查。 如果发现任何漏洞,npm 会给我们安全建议。
我们可以运行 npm audit fix 来修复包漏洞,如果可能的话,依赖树将被修复。
Yarn 和 npm 都使用加密哈希算法来确保包的完整性。
5.功能比较
5.1 生成一个lock文件(npm和yarn共有)
npm 和 Yarn 都在package.json文件中跟踪项目的依赖项,版本号并不一定是固定的,我们可以定义版本的一个范围。
为避免包版本不匹配,确切安装的版本被记录在包锁定文件中。每次添加模块时,npm 和 Yarn 会分别创建(或更新)一个 package-lock.json 和 yarn.lock 文件。这样,我们可以保证另一台机器安装完全相同的包,同时仍然在 package.json 中定义了一系列允许的版本。
5.2远程运行脚本(npm和yarn共有)
npx 命令用于从 ./node_modules/.bin 运行脚本,在运行它时,执行下列流程:
- 去
node_modules/.bin路径检查npx后的命令是否存在,找到之后执行; - 找不到,就去环境变量
$PATH里面,检查npx后的命令是否存在,找到之后执行; - 还是找不到,自动下载一个临时的依赖包最新版本在一个临时目录,然后再运行命令,运行完之后删除,不污染全局环境。 例如,可以通过运行以下命令来创建一个新的 React 应用程序:
npx create-react-app my-app
在 Yarn 中,您可以使用等效的 dlx 命令获得相同的结果:
yarn dlx create-react-app my-app
5.3零安装(yarn独有)
零安装将缓存存储在您项目目录中的.yarn 文件夹中。 当使用 yarn 或 yarn add package等命令时,Yarn 将创建一个 .pnp.cjs 文件。 该文件包含项目包的依赖关系层次结构。 因此,我们几乎可以在零时间访问它们。
5.4即插即用(yarn独有)
即插即用是另一种安装策略。 Yarn不生成 node_modules ,而是生成单个 .pnp.cjs 文件,该文件将映射packages在磁盘上的位置以及它们的依赖项列表。 这个特性可以带来更快的项目启动、更好的优化依赖树、更快的安装时间,当然也不需要 node_modules 文件夹。
5.5 Licenses(yarn独有)
Yarn 包含一个内置的Licenses检查器,当我们开发应用程序时,它可能会比较有用。
6.Yarn vs npm:选择哪个包管理器
作为一般指南,给出以下建议:
如果您对当前的工作流程感到满意,不想安装额外的工具,并且您没有很多磁盘空间,请选择 npm。
如果你想要一些很棒的功能,比如即插即用,你需要一些 npm 中没有的功能,并且你有足够的磁盘空间,请选择 Yarn。
如果你仍然很难在 npm 和 Yarn 之间做出明确的决定,那么你可以考虑 pnpm,它试图结合两个包管理器的优点,是包管理器中的第三个选择项。
作者:Ashish Lahoti 译者:前端很美 来源:sitepoint