这篇文章已经被 Adrian Sandu, Marcello La Rocca, Matt Burnett, Nuria Zuazo and Vildan Softic 审稿过了。
Yarn 是由 Facebo,google,Exponent 和 Tilde 制作的一种新的JavaScript 软件包管理器。可以在官方公告上看到,其目的是解决团队在 npm 面临的问题,即
- 安装包不足够 快/连续
- 有安全隐患,npm 允许安装包执行代码
但是,别慌! 这并不是说要去完全替代 npm。yarn 是从 npm 注册表获取模块的唯一的一个新的CLI 客户端。对注册表本身没有任何的改变——你依旧可以跟以前一样获取和发布包。
现在所有人都应该上 Yarn 的宣传车了吗?这些都是你用 npm 体验不到的。在这篇文章,我们将比较 npm 和 yarn,你可以比较哪个更适合你。
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 存在的时候更新它。
平行安装
无论什么时候 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 <package>
的时候,递归地列出所有已安装的包。相反 yarn 一点都不详细。当细节可以通过其他命令时,它使用贴切的表情展示出相当少的信息(除非是在 windows 上)。
Yarn vs npm: CLI 的区别
除了一些功能差异, Yarn 也有不同的命令。有些 npm 已经删除的命令,还有修改和添加了一些有趣的命令。
yarn global
不像 npm , 全局操作在使用 -g
或者 --global
标志的命令的时候执行,Yarn 命令需要带有 global
前缀。跟 npm 一样,特定项目的依赖不需要全局安装。
global
前缀只对 yarn add
, yarn bin
,yarn ls
和 yara remove
有效。除了 yarn add
,这些命令跟 npm 的是等价的。
yarn install
npm install
命令会从 package.json
文件安装依赖,并且允许添加新的包。
yarn install
仅仅顺序的安装 yarn.lock
或者 package.json
列出的依赖。
yarn add [–dev]
跟 npm install <package>
一样,yarn add <package>
允许你添加或者安装一个依赖。
正如命令名称所暗示的一样,它添加了一个依赖,意味着它会自动保存一个包的引用到 package.json
中,就跟 npm 的 --save
标志做的一样。
Yarn 的 --dev
标记添加包作为开发依赖,就跟 npm 的 --save-dev
标记一样。
- yarn add documentation
- npm install documentation
yarn licenses [ls|generate-disclaimer]
在撰写本文的时间为止,没有npm等效可用。
yarn licenses ls
列出了所有安装包的许可证。
yarn licenses generate-disclaimer
生成一个免责声明包含所有执照的所有包的内容。在你的项目中,你必须包括项目的许可证,在这些状态下,这是一个相当有用的工具。
- yarn licenses documentation
yarn why
这个命令窥探到依赖图,找出为什么包是安装在您的项目。也许你显式地添加它,也许这是一个依赖的包安装。yarn why
帮助你弄清楚。
- yarn why documentation
yarn upgrade [package]
这个命令会更新包到符合设置在 package.json
版本的最新的版本并且重建 yarn.lock
。这类似于 npm update
.
有趣的是,当指定一个包,包会更新到最新版本和更新package.json中定义的标签。这意味着该命令可能更新包到一个新的主要版本
- yarn upgrade documentation
yarn generate-lock-entry
yarn generate-lock-entry
命令基于 package.json
的依赖生成一个 yarn.lock
文件。这类似于 npm shrinkwrap
。这个命令应该小心使用,当通过 yarn add
和 yarn upgrade
添加和更新依赖的时候,lock 文件会自动生成和更新。
- yarn generate-lock-entry documentation
- npm shrinkwrap documentation
稳定性和可靠性
Yarn 宣传火车会出轨? 在第一天发布到公众的时候,确实收到了很多的问题,但是解决问题的速度也是惊人的。同时声明,社区正在努力查找和删错 bugs。看问题的数量和类型, Yarn 对于大多数用户来说是稳定的,但可能不适合边界情况。
注意,尽管包管理器对您的项目可能是至关重要的,它只是一个包管理器。如果出现错误,重新安装包也不困难,而不是重新回到 npm 的怀抱。
网友评论
为什么会这样,我猜, 是因为两次安装在不同时间,而在这段时间内正好一个版本更新了?
还是有其他原因