如何在React Native中使用Yarn 3
Yarn Berry(又称Modern Yarn或Yarn 2+)是经典Yarn的替代品,它提供了性能改进、对工作区的更好支持以及更简洁的开发者体验。
它最引人注目的功能之一是Plug-n-Play(以下简称 "PnP"),这是一种激进的依赖性管理新方法,无需运行yarn install ,并抛弃了node_modules 文件夹。
然而,React Native是唯一不支持PnP的著名项目之一,而且这不太可能很快改变。
本文将解释什么是PnP,为什么React Native不支持它,以及我们如何绕过它来享受Yarn 3的大部分优势。
什么是PnP?
在 Classic Yarn(和npm )中,我们在名为package.json 的清单文件中定义我们的依赖关系。我们称这些为直接依赖关系。然而,我们的依赖关系也可以有自己的依赖关系。这些是我们的过渡性依赖关系。
每个依赖关系都有许多自己的依赖关系,形成一棵 "依赖树",这很正常。这个树状结构被存储在yarn.lock ,以防止不同版本的软件包管理器创建不同的树状结构,这可能会导致各种意外行为。
当我们运行yarn install时,完整的依赖树会使用文件和文件夹重新创建,并存储在一个名为node_modules 的文件夹中。
在PnP中,我们没有一个node_modules 的文件夹。相反,每个直接的和横向的依赖被压缩成一个zip文件,然后存储在.yarn/cache 。一个名为.pnp.js 的文件包含"魔法",允许节点从这个新结构中读取依赖关系。由于我们的node_modules 文件夹的大小和复杂性(以及所有这些其他的原因),我们不应该提交,但提交这些压缩文件很简单:每个依赖关系一个文件。
现在我们有了一个提交了依赖关系的仓库,在切换分支或签出项目时就不需要运行yarn install 。由于这个原因,PnP也被称为 "零安装"。
为什么PnP不能用于React Native?
简单地说。React Native的假设是依赖于node_modules 文件夹的存在。由于PnP中没有node_modules ,这些引用需要被更新。
2018年底,在react-native-community/cli 上开了一个Github问题,以跟踪PnP支持方面的进展。然而--几乎四年过去了--并没有什么进展。
前Meta工程师Christoph Nakazawa 今年早些时候在推特上说,内部曾尝试过一个开关Yarn Berry,但由于技术问题而放弃了。看起来PnP支持在Meta不是一个优先事项,所以我们现在能做的最好的事情就是围绕它来做。
引入nodeLinker
为了让React Native满意,我们需要把node_modules 。值得庆幸的是,Yarn 3包括一个单行配置选项,使之变得简单。
配置是通过一个.yarnrc.yml 文件完成的,这个文件通常在你项目的根目录下。在这个文件中添加nodeLinker: node-modules ,可以指示Yarn在我们运行yarn install 时创建node_modules 文件夹,就像传统Yarn一样。这意味着我们仍然可以在.yarn/cache 中缓存我们的依赖,并将它们提交到 repo 中,同时也满足 React Native 的要求。
显然,我们不能再把这称为 "零安装",但这一步最多只需要几秒钟。由于依赖树是预先计算好的,而且所有的依赖都存在于磁盘上的.yarn/cache ,唯一限制这个步骤速度的是磁盘写入速度,因为我们从缓存中组装了巨大的node_modules 文件夹。
迁移
下面是如何让你的项目迁移。
这是对官方迁移指南的一个总结,你也应该阅读。
该指南假定你没有使用新的选择加入的Node Corepack功能。尽管这是Yarn团队安装新版本的首选方式,但它在Node中仍被标记为 "实验性",所以我们暂时选择不使用。
- 运行
**yarn set version berry**在你的软件仓库中。
这个命令将下载最新的Yarn 3二进制文件,存储在.yarn/releases,并创建一个.yarnrc.yml文件。 - 添加
**nodeLinker**选项。
在.yarnrc.yml,添加nodeLinker: node-modules - 更新你的
**.gitignore**.
添加以下几行。
.yarn/* !.yarn/cache !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/sdks !.yarn/versions - 更新脚本。**
用**yarn dlx替换yarn global为什么?
将yarn --frozen-lockfile替换为yarn --immutable - 更新自定义注册表设置。
在经典的Yarn中,.npmrc是用来定义自定义注册表设置的。在Yarn Berry中,它们必须被定义在.yarnrc.yml。
注意,你可以同时拥有一个全局的和一个特定项目的.yarnrc.yml。
这个步骤只适用于你使用需要自定义配置的私人托管包。 - 安装。
运行yarn。你的锁文件将被迁移,你所有的依赖将被缓存在.yarn/cache。 - 提交。
Git添加所有新缓存的依赖关系。最初的差异会有几百个文件,但在未来添加和更新软件包时,每次只需改变几个文件。 - 推送。
当其他的贡献者拉动回购时,他们会自动开始使用提交的Yarn 3二进制文件。不再需要管理工具版本🚀
享受时间
现在你可以享受Yarn 3的(大部分)优势,即使没有React Native的一流支持。在我看来,光是性能上的改进就使其成为绿地项目的明确选择,而安装时间的减少可以为你在CI中节省不少钱。