之前有同事说 npm 速度太慢了,项目部署也偶尔会发生依赖无法下载导致构建失败的问题,所以再次查阅学习了下包管理器的选型问题。
是什么
先分别说说两个包管理器吧
npm
npm 是 Node.js 的包管理工具,用来安装各种 Node.js 的扩展,能解决 NodeJS 代码部署上的很多问题。
yarn
yarn 是由 Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具,yarn 是为了弥补 npm 的一些缺陷而出现的。
npm 不受欢迎?
提到 npm vs yarn 网上可以搜索到很多结果都是偏向于 yarn,很多博客文章都在 diss npm 的种种不是:
- 依赖安装慢
- 安装时无法保持一致性
- 安装时报错信息易被警告信息淹没而被忽略
- 不同项目重复安装同一依赖占用磁盘空间
同时在标榜 yarn 这个工具是多么的好:
速度快
- 并行安装:yarn 并行执行所有任务,提高了性能,不像 npm 是队列执行。
- 离线模式:已经安装过的软件包,yarn 再次安装时会从缓存获取,不像 npm 那样再次从网络下载。
版本统一
yarn 通过锁定文件(lock file)记录被确切安装上的模块版本号。新增模块后,Yarn 就会创建(或更新)yarn.lock 这个文件保证每次拉取同一个项目依赖时,使用的都是一样的模块版本。
输出简洁
默认情况结合了 emoji 直观且直接地打印出必要的信息,提供了一些命令供开发者查询额外的安装信息。npm 是打印所有的安装依赖。
多注册来源处理
依赖包不管它被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装防止出现混乱不一致。
语义化
命令的名称更加语义了,例如:yarn add/remove
总之,能搜到的很多信息里面,大多对于 npm 这个评价都是不如 yarn 的,给大家造成了 yarn 比较香的第一印象,yarn 出现就是为了解决 npm 的缺陷 😂。
真是如此吗
仔细去看的话,其实会发现有很多信息都是过时的,就是在当时那个环境下是对的,但是 被 diss 久了,肯定要有所作为的,npm 也是在不断进步的。
下面就说说 npm7 吧。
- npm 7 已发布到 npm 仓库的最新版本。
- 执行
npm install --global
时将默认安装 npm 7。
Workspaces
npm CLI 的一组功能,可支持从单个顶级软件包中管理多个软件包
npm7 在性能上做了不少优化:
- 依赖包数量上减少了 54%(npm 7 67 个,npm 6 123 个)
- 代码测试覆盖率增加了 54%(npm 7 94% vs npm 6 77%)
可以参考下benchmarks中显示的性能提升
npm7 会修改 lockfile
新的 lockfile 格式,该格式会向后兼容 npm 6 用户,旧版本中,yarn.lock 文件被忽略,npm CLI 现在可以使用 yarn.lock 作为 package 元数据和依赖的来源。如果存在 yarn.lock,则 npm 还将使它与 package 的内容保持最新。
使用 npm 7 并且在有 v1 的 lockfile 的项目中执行 npm install,则会把 lock file 文件的内容取代成 v2 的格式。
- 避免方式:执行
npm install --no-save peer dependencies
自动安装 peer dependencies
npm 7 之前版本(4-6)中,开发人员需要自己管理和安装 peerDependencies,peer dependencies 冲突会有版本不兼容的警告,但仍会安装依赖并不会抛出错误。
npm 7 中,如果存在无法自动解决的依赖冲突,将会阻止安装。
新的 peer dependencies 可确保在 node_modules 树中 peerDependencies 的位置处或之上找到有效匹配的 peerDependencies。
可以通过使--force 选项重新安装来绕过冲突,或者选择--legacy-peer-deps 选项 peer dependencies 的依赖关系(类似于 npm 版本 4-6)。
许多包都依赖宽松的 peer dependencies 解析,npm 7 将打印警告并解决包依赖树中存在的大多数同级冲突,因此这些冲突不能手动处理。要在所有层级强制执行严格正确的 peer dependencies 依赖关系,需要使用 --strict-peer-deps 选项。
npm 的内部结构已得到重大重构。速度其实也与 yarn 不相上下了,所以选择哪一个都可以。
如果你已经在个人项目上使用 yarn,并且没有遇到更多问题,目前完全可以继续使用。但如果有兼容 npm 的场景,或者项目在使用 npm,cnpm 的团队,以及还没有切到 yarn 的情况,那就可以去试一试 npm7 。