Yarn Vs Npm

Author Avatar
Max Zhang 3月 01, 2018

原文出处

https://div.io/topic/1842

yarn结构

在 Node 生态系统中,依赖通常安装在项目的 node_modules 文件夹中。然而,这个文件的结构和实际依赖树可能有所区别,因为重复的依赖可以合并到一起。npm 客户端把依赖安装到 node_modules 目录的过程具有不确定性。这意味着当依赖的安装顺序不同时,node_modules 目录的结构可能会发生变化。这种差异可能会导致类似“我的机子上可以运行,别的机子不行”的情况,并且通常要花费大量时间定位与解决。

Yarn 通过 lockfiles 文件以及一个确定性的、可靠的安装算法,解决了版本问题和 npm 的不确定性问题。Lockfile 文件把安装的软件包版本锁定在某个特定版本,并保证 node_modules 目录在所有机器上的安装结果都是相同的。Lockfile 还使用简洁的有序键名的格式,保证了每次的文件变化最小化,进行代码审查也更为简单。

安装过程分为以下三个步骤:

处理: Yarn 通过向代码仓库发送请求,并递归查找每个依赖项,从而解决依赖关系。
抓取: 接下来,Yarn 会查找全局的缓存目录,检查所需的软件包是否已被下载。如果没有,Yarn 会抓取对应的压缩包,并放置在全局的缓存目录中,因此 Yarn 支持离线安装,同一个安装包不需要下载多次。依赖也可以通过 tarball 的压缩形式放置在源码控制系统中,以支持完整的离线安装。
生成: 最后,Yarn 从全局缓存中把需要用到的所有文件复制到本地的 node_modules 目录中。
通过清晰地细分这些步骤,以及确定性的算法支持,使得 Yarn 支持并行操作,从而最大化地利用资源,并加速安装进程。在一些 Facebook 的项目上,Yarn 甚至可以把安装过程降低一个数量级,从几分钟到只需几秒钟。Yarn 还使用了互斥锁,以确保多个 CLI 实例同时运行时不会互相冲突与影响。

纵观整个过程,Yarn 对于软件包安装加上了严格的限制。你可以对哪个生命周期脚本作用于哪个软件包进行控制。软件包的 checksum 也会存储在 lockfile 中,以确保每一次安装都可以得到同一个包。

特性

Yarn 除了让安装过程变得更快与更可靠,还添加了一些额外的特性,从而进一步简化依赖管理的工作流。

同时兼容 npm 与 bower 工作流,并支持两种软件仓库混合使用
可以限制已安装模块的协议,并提供方法输出协议信息
提供一套稳定的公有 JS API,用于记录构建工具的输出信息
可读、最小化、美观的 CLI 输出信息

Yarn vs npm: 功能上的差异

乍一看,yarn 和 npm 看起来差不多。当我们看下底层的时候,我们可以知道 yarn 不一样在哪里。

yarn.lock 文件

packege.json 文件可以让 npm 和 yarn 跟踪到项目的依赖,但是其版本号并不总是很准确。相反,你可以定义一个版本范围。这种方式,你可以选择包的一个特定的主要和次要的一个版本,但允许npm 安装最新的补丁(可以修正一些错误)。

在一个理想世界的语义版本,补丁版本不包含任何重大更改。不幸的是,这并不总是对的。npm 采用的策略可能会导致同一package.json文件两机,具有不同版本的安装包,可能引入错误。 npm 采用的策略可能会导致同一 package.json文件两机,安装不同版本的安装包,可能会造成引入错误。

为了避免包版本引入错误,一个确切的安装版本被固定在一个 lock 文件中。每次加入一个模块, yarn 便创建(或更新)一个 yarn.lock 文件。 这种方式可以保证另一台机器上安装同样的包,同时还可以在package.json中定义一系列允许的版本。在 npm 中, npm shrinkwrap 命令也可以生成一个 lock 文件,然后 npm install 在读 package.json 前,先从 lock 文件中读取,就像 yarn 先读 yarn.lock文件先一样。重要的区别是 yarn 总是创建和更新 yarn.lock,而 npm 不会只创建一个默认的并且仅仅在 npm-shrinkwrap.json 存在的时候更新它。

yarn.lock 文档
npm shrinkwrap 文档

平行安装

无论什么时候 npm 或者 yarn 需要安装一个包,它会执行一系列的任务。
在 npm,这些任务按顺序并且在每个包中都执行,意味着它将会在一个包完全安装的时候才跳到下个包。
yarn 则并行的执行这些任务,提高了性能。
相比之下,我在没有 shrinkwrap/lock 文件和缓存的情况下, 使用 npm 和 yarn 安装 express 包。总共安装了 42 个包。

npm: 9 秒 yarn: 1.37 秒
重复相同的步骤还是产生类似的结果。然后我安装 gulp , 结果有 195 个依赖包。

npm: 11 秒 Yarn: 7.81 秒
似乎较小的区别取决于正在安装包的数量。无论哪种方式, yarn 始终更快。

更简洁的输出(cleaner output)

默认情况下 npm 的输出非常详细。比如,它在执行 npm install 的时候,递归地列出所有已安装的包。相反 yarn 一点都不详细。当细节可以通过其他命令时,它使用贴切的表情展示出相当少的信息(除非是在 windows 上)。

Yarn vs npm: CLI 的区别

除了一些功能差异, Yarn 也有不同的命令。有些 npm 已经删除的命令,还有修改和添加了一些有趣的命令。

稳定性和可靠性

Yarn 宣传火车会出轨? 在第一天发布到公众的时候,确实收到了很多的问题,但是解决问题的速度也是惊人的。同时声明,社区正在努力查找和删错 bugs。看问题的数量和类型, Yarn 对于大多数用户来说是稳定的,但可能不适合边界情况。

注意,尽管包管理器对您的项目可能是至关重要的,它只是一个包管理器。如果出现错误,重新安装包也不困难,而不是重新回到 npm 的怀抱。

作者:lucy_
链接:https://www.jianshu.com/p/2db9f278494a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。