Yarn vs npm的大同小异&Yarn是什么?
-
- 一、Yarn、npm是什么?
- [二、Yarn vs npm:特性差异](#二、Yarn vs npm:特性差异)
- 总结
一、Yarn、npm是什么?
npm是Node.js的包管理器,是由Chris Korda维护。
npm,它全称为Node Package Manager,是随同Node.js一起安装的包管理工具。主要功能包括:
- 管理依赖:帮助开发者安装、卸载和管理项目中用到的各种软件包和库。
- 简化部署:通过自动化的方式解决Node.js代码部署中遇到的依赖问题。
- 分发代码:允许用户从NPM服务器下载别人编写的第三方包到本地使用。
总的来说,npm作为Node.js生态的一个重要组成部分,为JavaScript开发者提供了一个丰富的软件包生态系统,极大地促进了开发效率和代码共享。
Yarn :
是Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 --- Yarn,正如官方文档
中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的:
- npm 安装包(packages)的速度不够快,拉取的 packages 可能版本不同
- npm 允许在安装 packages 时执行代码,这就埋下了安全隐患
但是,Yarn 没想要完全替代 npm,它只是一个新的 CLI 工具,拉取的 packages 依然来自 npm 仓库。仓库本身不会变,所以获取或者发布模块的时候和原来一样。
那么既然都是从相同的拉取第三方包,而且二者作用几乎相同,那为什么要退出Yarn呢,请看下面它们的差异!
二、Yarn vs npm:特性差异
(1)yarn.lock 文件:解决版本一致问题
-
npm 和 Yarn 都是通过 package.json 记录项目需要拉取的依赖模块,不过在使用时,往往 package.json 中模块的版本号不太会写得非常确切,通常是定个版本范围。这样你就能自行选择使用模块的大版本或者小版本,也允许 npm 拉取模块最新的修复了 bug 的版本。
-
在理想的语义化版本世界中,新版是不会有颠覆旧版本的改变,然而现实并非如此。这就导致了使用 npm 拉取依赖时,即使用的是相同的 package.json,在不同的设备上拉到的 packages 版本不一,这就可能为项目引入 bug。
-
为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。
-
npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。
(2)并行安装
无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。
- npm 是按照队列执行每个 package,也就是说必须要等到当前 package 成功安装之后,才能继续后面的安装。
- 而 Yarn 是同步执行所有任务,提高了性能。
通过拉取 express 依赖,比较了 npm 和 Yarn 的效率,在没有用任何锁定文件(也就是没有缓存)的前提下,一共安装 42 个依赖:
- npm 耗时 9 秒
- Yarn 耗时 1.37 秒
所以 npm 和 Yarn 在安装包的速度差异和要安装的包个数强相关,不过不管怎么样,Yarn 都比 npm 要快。
(3)输出更简洁
- npm 的输出信息比较冗长。在执行 npm install 的时候,命令行里会不断地打印出所有被安装上的依赖。
- 相比之下,Yarn 简洁太多:默认情况下,结合了 emoji (Windows 上 emoji 不可见)直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。
(4)CLI 区别
相比于 npm 的命令,Yarn 命令有增有减还有一些更改。
-
yarn global
- npm 的全局操作命令要加上 -g 或者 --global 参数;
- Yarn 的全局命令则需要加上 global。和 npm 类似,项目特定的依赖,就不需要全局安装了。
当执行
yarn add、yarn bin、yarn ls 和 yarn remove
时添加 global 前缀才是有全局作用。除了 yarn add 之外,其他三个命令和 npm 的一样。如:
yarn global add nodemon --prefix /usr/local
-
yarn install
npm install 命令安装的是 package.json 中的依赖,如果开发者在 package.json 中添加了新的依赖,npm install 也一样安装。然而,yarn install 会优先安装 yarn.lock 中记录的依赖,没有这样的锁定文件时,才会去安装 package.json 中的依赖。
-
yarn add [--dev]
和 npm install 类似,yarn add 命令允许你添加并安装依赖。通过这个命令添加的依赖都会被自动加到 package.json 中,和我们在 npm 命令中使用 --save 参数一样。Yarn 的-dev 则等同于 npm 的 --save-dev。
-
yarn licenses [ls|generate-disclaimer]
yarn licenses ls 用于罗列出所有被安装的 package 所持有的执照情况。yarn licenses generate-disclaimer 将生成一个对所有依赖的免责声明。有些执照要求开发者一定要在项目中包含这些它们,这个命令就是为这样的场景存在的。
-
yarn why
这条命令能帮助开发者理清安装的 package 之间的关系。拉取了各种依赖以后,有些 package 是你显式安装的,有些包则是递归依赖的。
-
yarn upgrade [package]
这条命令将根据 package.json 将 package 升级到最新版本,并更新 yarn.lock,和 npm update 相似。
有意思的是,如果指定了 [package] 参数,Yarn 会将 package 升级到最新版本,并更新 package.json 中该 package 的版本号字段。
-
yarn generate-lock-entry
这条命令将会生成一份基于 package.json 的 yarn.lock 文件,作用和 npm shrinkwrap 类似。不过由于执行 yarn add andyarn upgrade 时都会更新 yarn.lock 文件,所以要慎重执行 yarn generate-lock-entry 命令
总结
目前看来 Yarn 要比 npm 更好用:默认就有锁定文件、更快速地安装依赖以及依赖的更新会自动同步到 package.json 文件中。从 npm 迁移到 Yarn 成本几乎为零,以上优点都让 Yarn 成为了目前 npm 最好的替代品。