- 原文地址:To Yarn and Back (to npm) Again
- 原文作者:Spencer Brown
- 译文出自:掘金翻译计划
- 本文永久链接:github.com/xitu/gold-m…
- 译者:DM.Zhong
- 校对者:Starriers,wyh888
去年,我们决定将所有 JavaScript 项目从 npm 迁移到 Yarn。
之所以这样做,有以下两个主要原因:
yarn install
比npm install
快 20 倍。npm install
在我们的一些大型项目中往往需要消耗 20 分钟以上。- Yarn 的依赖锁定比 npm 的更加可靠。
查看去年的一篇博客(链接在上方给出了)可以了解更多。
使用 Yarn 的 13 个月
Yarn 解决了我们在使用 npm 时所遇到的一些烦人的问题,但是它自身也带来了许多的问题:
- Yarn 出现了非常不好的回归,这让我们不太敢升级它。
- Yarn 经常会在你运行
add
,remove
或者update
的时候生成无效的yarn.lock
文件。这就使得开发者需要做一些冗余的工作来remove
和add
这些有冲突的包,直到 Yarn 找出解决方案以使得yarn check
能够通过,才能改善这一现象。 - 很多时候,因为 Yarn 进行了优化,所以当开发人员在拉取项目的最新变化后运行
yarn
时,他们的yarn.lock
文件会变的很“脏”,。为了解决这个问题,需要开发人员推送与他们工作无关的更改。Yarn 需要在使用命令yarn lock
更新时立即优化,而不是在下一次使用yarn
命令时。 yarn publish
不是很可靠(存在问题?)(tracked issues #1, tracked issue #2),这意味着我们不得不使用npm publish
来发布包。这使我们很容易忘记在这种特殊场景下需要使用 npm,并且意外地使用 Yarn 发布包导致发布的包无法安装。
不幸的是,在我们使用 Yarn 的 13 个月里,这些工作流很混乱的问题一个都没有被修复。
在经历了特别痛苦的几个星期(经常开 15 分钟的 Yarn 问题解决会议)后,我们决定回归到 npm。
npm 6
在我们使用 Yarn 的这段时间里,npm 做出了重大的改善,以期拥有 Yarn 的速度及其依赖锁定的可靠性 —— 这些问题曾使得我们转向了 Yarn。就像 Yarn 里面的那些烦人的问题一样,我们无法离开这些好处,因此我们首先需要验证一下 npm 是否解决了原来的那些问题。
我们决定尝试一下当前能够获取到的最新版本的 npm,npm@6.0.0
,因为我们想要利用尽可能多的速度改善和 bug 修复。据传 npm@6.0.0
是一个相对较小的重大更新,因此我们认为使用它不会冒很大的风险。不可思议的是,npm@5.8.1
使我们在 6.0.0 发布之前测试过的版本,在我们许多开发工程师的机器上(OS X Sierra/High Sierra,node@v8.9.3
)安装依赖失败了,出现了许多错误(比如 cb() never called!
)。
速度
我们很高兴地发现,在每个包管理器试用五个案例后,npm的平均成绩与 Yarn 相当:
- Yarn:
$ rm -rf node_modules && time yarn
:126s - npm:
$ rm -rf node_modules && time npm i
:132s
在正确的方向上迈出了正确的一步。我们的试验还会继续 :)。
Locking
npm 在 npm@5.0.0
引入了 package-lock.json
等价于 Yarn 中的 yarn.lock
。npm shrinkwrap
仍然可以被用于创建 npm-shrinkwrap.json
文件,但是根据 npm 文档的描述,这些文件的使用场景有了一些不同:
推荐的 npm-shrinkwrap.json 使用场景是通过发布过程在注册表中部署的应用程序:例如,用作全局安装或 devDependencies 的守护程序和命令行工具。对于库作者发布这个文件非常不鼓励,因为这会阻止最终用户控制传递依赖关系更新。
另一方面,package-lock.json
文件不跟随包一起发布。这相当于 Yarn 如何不尊重依赖关系的 yarn.lock
文件 —— 父项目管理自己的依赖关系和子依赖关系(但要注意的是,如果库的确在不应该的时候发布 npm-shrinkwrap.json
文件,那么您将不得不使用它们的依赖性)。
Locking 验证
npm 没有与 Yarn 的 yarn check
相对应的功能,但 yarn check
看起来像一些人(如 Airbnb)使用 npm ls> / dev / null
来检查安装错误,如缺少软件包。
不幸的是,检查将 peer 依赖警告视为错误,这使得我们无法使用它,因为我们经常通过 CDN 实现 peer 依赖关系。
npm 最近引入了 npm ci
,很幸运它提供了一些验证功能。npm ci
确保了 package-lock.json
和 package.json
在同一验证形式下是同步的。它同样提供了一些其它好处 —— 查看文档了解更多。
之前在使用 npm 时,我们从未意识到 install
的不一致性(似乎只有 Yarn 有这些问题 :)),因此我们认为只使用 npm ci
是安全的。
使用 Yarn 的烦恼
除了追上 Yarn 的速度和拥有 Yarn 依赖关系锁定的保证之外,npm 似乎没有任何使用 Yarn 时困扰我们的问题!
Check, check, check
npm@6.0.0
为我们检查了所有的盒子,所以我们决定以后继续使用它!
在对我们的一个服务进行为期三周的试验成功后,我们将剩余的其它服务和项目也迁移到了 npm!
建议
deyarn
我们已经发布了一个叫做 deyarn
的开源模块,它可以帮助你将项目从 Yarn 迁移到 npm。
通过 engines
强制使用 npm
我们推荐使用 engines
选项,它可以让你避免在应该使用 npm 的时候却意外地使用了 Yarn 了。
我们已经添加了一个配置如下:
{
"engines": {
"yarn": "NO LONGER USED - Please use npm"
}
}
对于我们内部项目的所有的 package.json
而言。deyarn
(链接在上方给出)会帮你管理 :)。
试试它!
我们测试过这个工作流能够满足我们的需求,并且我们也推荐你使用它。如果你需要一个极致快速的包管理器,然后你会发现 Yarn 仍然是最佳之选。但是如果你需要一个建立起来比较简单的包管理器,我们发现 npm 6 在速度与可靠性上保持了很好的平衡。
如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。