Skip to main content

问题与解答

为什么 npm 上的 yarn 包仍然在 1.x 上?

¥Why is the yarn package on npm still on 1.x?

自 2019 年以来,Yarn 的现代版本尚未在 npm 上分发。

¥Modern releases of Yarn haven't been distributed on npm since 2019.

原因很简单:因为 Yarn 不是与 Node.js 一起分发的,所以许多人依赖 npm install -g yarn 之类的东西作为其图片构建的一部分。这意味着任何重大更改都会影响使用此模式的每个人,并破坏他们的部署。

¥The reason is simple: because Yarn wasn't distributed alongside Node.js, many people relied on something like npm install -g yarn as part of their image building. It meant that any breaking change would make their way on everyone using this pattern, and break their deployments.

因此,我们决定停用 yarn npm 包,仅将其用于所需的少数 1.x 维护版本。Yarn 现在直接从我们的网站安装,通过 Corepackyarn set version

¥As a result, we decided to retire the yarn npm package and only use it for the few 1.x maintenance releases needed. Yarn is now installed directly from our website, via either Corepack or yarn set version.

为什么要升级到 Yarn Modern?

¥Why should you upgrade to Yarn Modern?

虽然 Yarn Classic 系列 (1.x) 仍然是 JavaScript 生态系统的支柱,但我们建议尽可能升级。为什么?

¥While the Yarn Classic line (1.x) remains a pillar of the JavaScript ecosystem, we recommend upgrading if possible. Why's that?

  1. 新功能:除了你已经习惯的经典功能之外,还有你将发现的新功能(yarn dlx内置 patch: 协议 等),Modern 还提供插件来扩展 Yarn 的功能集,包括 changesetsconstraintsworkspaces

    ¥New features: On top of the classic features you're already used to, on top of the new ones you'll discover (yarn dlx, builtin patch: protocol, ...), Modern offers plugins extending Yarn's featureset with changesets, constraints, workspaces, ...

  2. 效率:Modern 具有新的安装策略,导致项目只是过去的一小部分;例如,在默认配置下,库存 CRA 工件现在仅占用 45MB,而不是 237MB。性能 也得到了改进,现在大多数安装只需几秒钟,即使是在非常大的项目上也是如此。我们甚至可以达到 零秒

    ¥Efficiency: Modern features new install strategies, leading projects to only be a fraction of their past self; as an example, under the default configuration the stock CRA artifacts now only take 45MB instead of 237MB. Performances were improved as well, with most installs now only taking a few seconds even on extremely large projects. We even made it possible to reach zero seconds!

  3. 可扩展性:Modern 的架构允许你根据需要构建自己的功能。你不再需要等待我们实现你梦寐以求的功能 - 你现在可以根据自己的规范自己做!重点工作区、自定义安装、项目验证……

    ¥Extensibility: Modern's architecture allows you to build your own features as you need it. No more of you being blocked waiting for us to implement this feature you dream of - you can now do it yourself, according to your own specs! Focused workspaces, custom installs, project validation, ...

  4. 稳定性:Modern 是在多年维护 Classic 的经验之后诞生的;它让我们最终解决了一些功能实现方式方面长期存在的设计问题。工作区现在是核心组件,解析管道已经精简,数据结构更高效……因此,Modern 不太可能受到错误假设和其他设计缺陷的影响。

    ¥Stability: Modern comes after years of experience with maintaining Classic; it allowed us to finally fix longstanding design issues with how some features were implemented. Workspaces are now core components, the resolution pipeline has been streamlined, data structures are more efficient... as a result, Modern is much less likely to suffer from incorrect assumptions and other design flaws.

  5. 面向未来:我们投资 Modern 的一个重要原因是我们注意到在 Classic 上构建新功能变得越来越困难 - 每个更改都很可能产生不可预见的后果。现代架构从我们的错误中吸取了教训,旨在让我们以更快的速度构建功能 - 从我们新获得的速度可以看出。

    ¥Future proof: A big reason why we invested in Modern was that we noticed how building new features on Classic was becoming difficult - each change being too likely to have unforeseen consequences. The Modern architecture learned from our mistakes, and was designed to allow us to build features at a much higher pace - as evidenced by our new gained velocity.

你认为从 Classic 到 Modern 的迁移有多容易?

¥How easy should you expect the migration from Classic to Modern to be?

通常,需要注意一些主要事项:

¥Generally, a few main things will need to be taken care of:

  1. 设置格式已更改。我们不再读取 .npmrc.yarnrc 文件,而是使用来自 .yarnrc.yml 文件 的设置。

    ¥The settings format changed. We don't read the .npmrc or .yarnrc files anymore, instead of consuming the settings from the .yarnrc.yml file.

  2. 某些第三方包未正确列出其依赖,需要通过 packageExtensions 设置来提供帮助。

    ¥Some third-party packages don't list their dependencies properly and will need to be helped through the packageExtensions settings.

  3. 对文本编辑器的支持非常好,但你需要运行我们 SDK 文档 中列出的一次性设置。

    ¥Support for text editors is pretty good, but you'll need to run the one-time-setup listed in our SDK documentation.

  4. 某些工具(主要是 React Native 和 Flow)需要通过将 nodeLinker 设置设置为 node-modules 来降级到 node_modules 安装策略。TypeScript 没有这个问题。

    ¥Some tools (mostly React Native and Flow) will require downgrading to the node_modules install strategy by setting the nodeLinker setting to node-modules. TypeScript doesn't have this problem.

大多数项目只会遇到这四个问题,这些问题都可以在一个下午的工作中解决。有关更详细的说明,请参阅详细的 迁移指南

¥Most projects will only face those four problems, which can all be fixed in a good afternoon of work. For more detailed instructions, please see the detailed migration guide.

哪些文件应该被 gitignored?

¥Which files should be gitignored?

如果你使用零安装:

¥If you're using Zero-Installs:

.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

如果你不使用零安装:

¥If you're not using Zero-Installs:

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

如果你有兴趣了解有关每个文件的更多信息:

¥If you're interested to know more about each of these files:

  • 可以安全地忽略 .yarn/cache.pnp.*,但你需要运行 yarn install 以在每个分支切换之间重新生成它们 - 否则将是可选的,参见 零安装

    ¥.yarn/cache and .pnp.* may be safely ignored, but you'll need to run yarn install to regenerate them between each branch switch - which would be optional otherwise, cf Zero-Installs.

  • .yarn/install-state.gz 是一个优化文件,你永远不必提交。它只是存储项目的确切状态,以便下一个命令可以启动,而无需再次解析工作区。

    ¥.yarn/install-state.gz is an optimization file that you shouldn't ever have to commit. It simply stores the exact state of your project so that the next commands can boot without having to resolve your workspaces all over again.

  • .yarn/patches 包含你使用 yarn patch-commit 命令生成的补丁文件。你总是希望它们在你的存储库中,因为它们是安装依赖所必需的。

    ¥.yarn/patches contain the patchfiles you've been generating with the yarn patch-commit command. You always want them in your repository, since they are necessary to install your dependencies.

  • .yarn/plugins.yarn/releases 包含当前存储库中使用的 Yarn 版本(由 yarn set version 定义)。你需要保持它们的版本控制(这可以防止潜在的问题,例如,如果两个工程师使用具有不同功能的不同 Yarn 版本)。

    ¥.yarn/plugins and .yarn/releases contain the Yarn releases used in the current repository (as defined by yarn set version). You will want to keep them versioned (this prevents potential issues if, say, two engineers use different Yarn versions with different features).

  • .yarn/sdks 包含由 @yarnpkg/sdks 生成的编辑器 SDK。是否将其保留在你的存储库中取决于你;如果没有,则需要在新的克隆上再次执行编辑器程序。有关更多详细信息,请参阅 编辑器 SDK

    ¥.yarn/sdks contains the editor SDKs generated by @yarnpkg/sdks. Whether to keep it in your repository or not is up to you; if you don't, you'll need to follow the editor procedure again on new clones. See Editor SDKs for more details.

  • .yarn/unplugged 可能应该始终被忽略,因为它们通常包含特定于机器的构建工件。但是,忽略它可能会阻止 零安装 工作(为防止这种情况,请将 enableScripts 设置为 false)。

    ¥.yarn/unplugged should likely always be ignored since they typically hold machine-specific build artifacts. Ignoring it might however prevent Zero-Installs from working (to prevent this, set enableScripts to false).

  • 版本插件 使用 .yarn/versions 来存储包发布定义。你需要将其保留在你的存储库中。

    ¥.yarn/versions is used by the version plugin to store the package release definitions. You will want to keep it within your repository.

  • yarn.lock 应始终存储在你的存储库 (即使你开发了一个库) 中。

    ¥yarn.lock should always be stored within your repository (even if you develop a library).

  • .yarnrc.yml(及其旧版本 .yarnrc)是配置文件。它们应该始终存储在你的项目中。

    ¥.yarnrc.yml (and its older counterpart, .yarnrc) are configuration files. They should always be stored in your project.

提示

你还可以添加 .gitattributes 文件以将发布和插件包标识为二进制内容。这样,Git 就不会在你随后每次添加或更新它们时显示大量差异:

¥You can also add a .gitattributes file to identify the release and plugin bundles as binary content. This way Git won't bother showing massive diffs when each time you subsequently add or update them:

/.yarn/releases/** binary
/.yarn/plugins/** binary

Yarn 支持 ESM 吗?

¥Does Yarn support ESM?

是的。

¥Yes.

首先,请记住 Yarn 支持 node-modules 安装策略,它安装的包与 npm 完全相同。因此,如果 Yarn 不支持 ESM,则什么都不会支持。如果你听到有人说不支持,他们实际上的意思是“Yarn PnP 不支持 ESM” - 除了它确实如此,自从 3.1 以来。

¥First, remember that Yarn supports the node-modules install strategy, which installs package exactly the same as, say, npm would. So if Yarn didn't support ESM, nothing would. If you hear someone say it doesn't, they actually mean "Yarn PnP doesn't support ESM" - except it does, ever since the 3.1.

因此,仅凭这一点就应该可以回答你的问题。但是如果你想要了解有关 PnP 和 ESM 故事的更多细节,那么让我们先谈谈 ESM 本身。ESM 有两点:从本质上讲,它是 ES2015 中起草的规范。但是,没有引擎立即实现它:此时,该规范几乎只是一个语法占位符,没有任何具体内容。直到 2019 年底,Node 才终于获得了对原生 ESM 的支持,而无需实验标志。但是这种支持有一个主要的警告:ESM 加载器不存在。加载器允许项目告诉 Node 如何在磁盘上定位包和模块。你可能知道其中一些:@babel/registerts-nodeJest 的模拟Electron 等等。

¥So this alone should answer your question. But if you want more details about the PnP and ESM story, then let's talk about ESM itself first. ESM is two things: at its core, it's a spec that got drafted in ES2015. However, no engine implemented it straight away: at this time the spec was pretty much just a syntactic placeholder, with nothing concrete underneath. It's only starting from late 2019 that Node finally received support for native ESM, without requiring an experimental flag. But this support had one major caveat: the ESM loaders weren't there. Loaders are the things that allow projects to tell Node how to locate packages and modules on the disk. You probably know some of them: @babel/register, ts-node, Jest's mocks, Electron, and many more.

与 CommonJS 不同,ESM 模块解析管道旨在完全与外部隔离,例如,多个线程可以共享同一个解析器实例。除其他事项外,这意味着,如果没有官方加载器支持,就不可能支持替代解析策略 - monkey-patching 解析原语不再可行,因此所有这些项目实际上都无法支持 ESM。这只能意味着一件事:ESM 还没有准备好。是的,它得到了原生支持,但考虑到它破坏了生态系统的很大一部分而没有任何替代方案,它不可能是一个合理的标准 - 目前。

¥Unlike CommonJS, the ESM module resolution pipeline is intended to be completely walled from the outside, for example so that multiple threads can share the same resolver instance. Amongst other things it meant that, without official loader support, it was impossible to support alternate resolution strategies - monkey-patching the resolution primitives wasn't viable anymore, so all those projects literally couldn't support ESM at all. It could only mean one thing: ESM wasn't ready. Yes, it was supported natively, but given it broke a sizeable part of the ecosystem with no alternative whatsoever, it couldn't be a reasonable standard - yet.

幸运的是,Node 发现了这个问题,开始研究加载器,并发布了第一个迭代。快进到今天,Node Loaders 仍然处于 繁重的工作 阶段(并且多次改变形状,正如这个 "experimental" 注释所强调的那样),但允许我们起草与 ESM 兼容的 PnP 加载器的第一个实现,我们在 3.1 中发布了它。凭借这些经验,我们开始为 Node Loaders 工作组做出贡献,不仅帮助 Yarn 自己的用例,还帮助其他容易效仿我们的项目的用例。

¥Fortunately, Node saw the issue, started to work on loaders, and shipped a first iteration. Fast forward to today, Node Loaders are still in heavy work (and changed shape more than once, as highlighted by this "experimental" annotation), but have allowed us to draft a first implementation of a ESM-compatible PnP loader, which we shipped in 3.1. Strong of those learnings, we started to contribute to the Node Loaders working group, not only to help Yarn's own use cases but also those from other projects susceptible to follow our lead.

加载器还不完美,除非它们是 ESM 专用包,否则不推荐使用,但有一条前进的道路,只要我们共同努力,我们就会到达那里。我们只是必须小心,在朝着目标前进时不要把人推到一边。

¥Loaders aren't perfect yet, and until they are ESM-only packages cannot be recommended, but there's a way forward and as we work together we'll get there. We just have to be careful not to push people aside as we run towards our goal.

是否应将锁定文件提交到存储库?

¥Should lockfiles be committed to the repository?

是的。

¥Yes.

锁定文件应始终与你的项目源一起存储 - 无论你是在编写独立应用还是分布式库,都是如此。

¥Lockfiles are meant to always be stored along with your project sources - and this regardless of whether you're writing a standalone application or a distributed library.

一个反对在存储库中签入锁文件的观点是,要意识到最新版本的库可能存在的问题。说这话的人认为,锁文件的存在会阻止贡献者看到此类问题,因为所有依赖都被锁定并且看起来没问题,直到消费者安装库并使用更新(且不兼容)的依赖。

¥One persisting argument against checking-in the lockfile in the repository is about being made aware of potential problems against the latest versions of the library. People saying this argue that the lockfile being present prevents contributors from seeing such issues, as all dependencies are locked and appear fine until a consumer installs the library and uses more recent (and incompatible) dependencies.

虽然很诱人,但这种推断有一个致命的缺陷:从存储库中删除锁文件并不能阻止此问题的发生。特别是:

¥Although tempting, this reasoning has a fatal flaw: removing the lockfile from the repository doesn't prevent this problem from happening. In particular:

  • 除非他们明确删除其安装工件(node_modules),否则活跃贡献者不会获得新版本,但这种情况可能并不常见。因此,有问题的依赖升级将主要由新贡献者发现,这不会带来良好的首次体验,并可能阻碍贡献。

    ¥Active contributors won't get new versions unless they explicitly remove their install artifacts (node_modules), which may not happen often. Problematic dependency upgrades will thus be mainly discovered by new contributors, which doesn't make for a good first experience and may deter contributions.

  • 即使假设你每周运行全新安装,你的升级也不会轻易可逆 - 一旦你测试了最新的软件包,就不会再针对较新的软件包进行测试。兼容性问题仍然存在,它们只是针对以前可以工作但你不再测试的包。换句话说,通过始终测试最新的 semver 版本,你将不会看到是否意外开始依赖以前不可用的功能。

    ¥Even assuming you run fresh installs every week, your upgrades won't be easily reversible - once you test the most recent packages, you won't test against the less recent ones. The compatibility issues will still exist, they just will be against packages that used to work but that you don't test anymore. in other words, by always testing the most recent semver release, you won't see if you accidentally start relying on a feature that wasn't available before.

当然,这些点只是问题的一部分 - 缺少锁定文件也意味着存储库中缺少关键状态信息。几个月后,当你或你的贡献者想要修复你的某个旧项目时,你可能甚至无法再构建它,更不用说改进它了。

¥Of course these points are only part of the problem - the lack of lockfile also means that key state information are missing from the repository. When months later you or your contributors want to make a fix on one of your old projects you might not even be able to build it anymore, let alone improve it.

锁定文件应始终保存在存储库中。持续集成测试是一个好主意,但应该留给持续集成系统。例如,Yarn 本身针对主要开源框架和工具的最新版本运行 每日测试,这使我们能够快速发现与最新版本的任何兼容性问题,同时仍然保证每个贡献者在使用项目时都会有一致的体验。DependabotRenovate 也是跟踪依赖更新的好工具。

¥Lockfiles should always be kept within the repository. Continuous integration testing is a good idea, but should be left to continuous integration systems. For example, Yarn itself runs daily tests against the latest versions of major open-source frameworks and tools, which allows us to quickly spot any compatibility issue with the newest release, while still being guarateed that every contributor will have a consistent experience working with the project. Dependabot and Renovate are also good tools that track your dependencies updates for you.

如何在工作区之间共享脚本?

¥How to share scripts between workspaces?

鲜为人知的 Yarn 功能:任何名称中带有冒号的脚本(build:foo)都可以从任何工作区调用。另一个鲜为人知的功能:$INIT_CWD 将始终指向运行脚本的目录。总之,你可以编写可以这样重用的脚本:

¥Little-known Yarn feature: any script with a colon in its name (build:foo) can be called from any workspace. Another little-known feature: $INIT_CWD will always point to the directory running the script. Put together, you can write scripts that can be reused this way:

{
"dependencies": {
"typescript": "^3.8.0"
},
"scripts": {
"g:tsc": "cd $INIT_CWD && tsc"
}
}

然后,从任何包含其自己的 tsconfig.json 的工作区,你将能够调用 TypeScript:

¥Then, from any workspace that contains its own tsconfig.json, you'll be able to call TypeScript:

{
"scripts": {
"build": "yarn g:tsc"
}
}

或者如果你只想从根工作区使用 tsc

¥or if you only want to use tsc from the root workspace:

{
"scripts": {
"build": "run -T tsc"
}
}

你是否想在项目基础上运行脚本:

¥Should you want to run a script in the base of your project:

{
"scripts": {
"build": "node ${PROJECT_CWD}/scripts/update-contributors.js"
}
}

Yarn 由 Facebook 运营吗?

¥Is Yarn operated by Facebook?

不。

¥No.

尽管 Yarn 的第一个版本是由 Sebastian McKenzie 在 Facebook 工作时实现的,但初始设计收到了来自其他各种公司的反馈(例如通过 Yehuda Katz波浪号),并且该项目被放入自己的 GitHub 组织。Facebook 在接下来的几年里继续对其进行投资(主要是因为它被证明是 RN 生态系统的重要组成部分),但主要贡献也来自开源。

¥Despite the first version of Yarn having been implemented by Sebastian McKenzie while working at Facebook, the initial design received feedbacks from various other companies (such as Tilde via Yehuda Katz) and the project was put into its own GitHub organization. Facebook kept investing in it during the following years (mostly because it proved to be a critical part of the RN ecosystem) but major contributions came from the open-source too.

如今,活跃的开发团队完全由非创始人公司雇用的人员组成。当然,Facebook 员工仍然欢迎为该项目做出贡献,但他们将经历与其他人相同的审查流程。

¥Nowadays, the active development team is composed exclusively of people employed by non-founders companies. Facebook employees are of course still welcome to offer contributions to the project, but they would go through the same review process as everyone else.

为什么是 registry.yarnpkg.com?Facebook 会跟踪我们吗?

¥Why registry.yarnpkg.com? Does Facebook track us?

不。

¥No.

当 Yarn 创建时,npm 注册表过去是通过 Fastly 提供的。这显然影响了安装性能,因此最初的团队决定与 Cloudflare 合作并设置一个 反向代理,以便在返回请求之前更好地缓存请求。此设置在我们这边甚至没有后端。

¥When Yarn got created, the npm registry used to be served through Fastly. This was apparently affecting the install performances, so the initial team decided to partner with Cloudflare and setup a reverse proxy that would simply better cache the requests before returning them. This setup didn't even have a backend on our side.

在某个时候,npm 也切换到了 Cloudflare,我们关闭了代理,用 CNAMEproof)替换它。出于可靠性原因,我们仍然保留主机名 - 虽然只要使用 Yarn,Yarn 域名就会一直得到维护,但 npm 域名不一定如此。这使我们能够在主要来源不可用时重定向到注册表的只读副本。

¥At some point npm switched to Cloudflare as well, and we turned off the proxy to replace it by a CNAME (proof). We still keep the hostname for reliability reasons - while it stands to reason that the Yarn domain name will keep being maintained for as long as Yarn is being used, the same isn't necessarily true of the npm domain name. That gives us the ability to redirect to a read-only copy of the registry should the primary source become unavailable.

虽然我们确实收集了一些基本的 客户端遥测,但没有 http 日志可以到达 Yarn 项目基础设施 - 更不用说 Facebook,它无法控制该项目(另请参阅 Yarn 由 Facebook 运营吗?)。

¥While we do gather some basic client-side telemetry, no http logs can ever even reach the Yarn project infrastructure - and even less Facebook, which has no control over the project (see also, Is Yarn operated by Facebook?).

registry.yarnpkg.com 的查询返回 404/500/...;它关闭了吗?

¥Queries to registry.yarnpkg.com return a 404/500/...; is it down?

不。

¥No.

正如 上一节 中提到的,Yarn 注册表只是 npm 注册表的 CNAME。由于我们甚至没有后端,任何服务器错误都只能来自 npm 注册表,因此应该向他们报告并在他们的 状态页面 上进行监控。

¥As mentioned in the previous section, the Yarn registry is just a CNAME to the npm registry. Since we don't even have a backend, any server error can only come from the npm registry and thus should be reported to them and monitored on their status page.

Yarn 比其他包管理器快吗?

¥Is Yarn faster than other package managers?

耸肩 🤷‍♀️

¥Shrug 🤷‍♀️

在 Yarn 发布时,Yarn 实际上比它的一些竞争对手快得多。不幸的是,我们未能强调性能并不是我们继续开发 Yarn 的主要原因。性能来来去去,所以虽然我们速度超快,但这并不是因为我们做得非常好,而是因为竞争实现有一个严重的错误。当该错误得到修复后,我们的沟通不畅变得更加明显,因为有些人认为 Yarn 只关心性能。

¥At the time Yarn got released Yarn was effectively much faster than some of its competitors. Unfortunately, we failed to highlight that performance wasn't the main reason why we kept working on Yarn. Performances come and go, so while we were super fast it wasn't so much because we were doing something incredibly well, but rather that the competing implementations had a serious bug. When that bug got fixed, our miscommunication became more apparent as some people thought that Yarn was all about performances.

简而言之,我们的差异在于我们的优先事项。不同的项目做出不同的权衡,这正是这里发生的事情。我们优先考虑工作区,因为我们觉得 monorepos 提供了重要的价值。我们投入了大量资源推动 Plug'n'Play(包括通过 对第三方项目的数十个贡献),因为我们觉得这对生态系统很重要。这是主要区别:我们会根据项目路线图做出自己的明智决定。

¥Put simply, our differences lie in our priorities. Different projects make different tradeoffs, and it's exactly what happens here. We prioritized workspaces because we felt like monorepos were providing significant value. We've spent significant resources pushing for Plug'n'Play (including through dozens of contributions to third-party projects) because we felt like this was important for the ecosystem. This is the main difference: we make our own informed decisions regarding the project roadmap.

速度是相对的,也是暂时的状态。流程、路线图和核心价值观才是关键。

¥Speed is relative and a temporary state. Processes, roadmaps and core values are what stick.

为什么即使我不使用 Plug'n'Play,TypeScript 也会被修补?

¥Why is TypeScript patched even if I don't use Plug'n'Play?

鉴于 PnP 是一种不同于 Node 的解析器标准,重新实现 require.resolve API 的工具需要添加一些逻辑来解释 PnP 解析。虽然各种项目都这样做了(例如 Webpack 5 现在开箱即用地支持 PnP),但仍有一些项目对此持观望态度。在 TypeScript 的情况下,我们启动并继续维护 拉取请求,但 TypeScript 团队仍然必须接受它。为了解除对用户的阻止,我们决定使用我们的新 patch: 协议 自动将此确切的拉取请求应用于下载的 TypeScript 版本。

¥Given that PnP is a resolver standard different from Node, tools that reimplement the require.resolve API need to add some logic to account for the PnP resolution. While various projects did so (for example Webpack 5 now supports PnP out of the box), a few are still on the fence about it. In the case of TypeScript we started and keep maintaining a pull request, but the TypeScript team still has to accept it. In order to unblock our users, we made the decision to automatically apply this exact pull request to the downloaded TypeScript versions, using our new patch: protocol.

这现在引出了一个问题:为什么即使 Plug'n'Play 被禁用,我们仍然会应用此补丁?主要原因是 Yarn 打算提供一致的行为。一些设置涉及在开发期间使用 node_modules 链接器(以避免必须设置编辑器 SDKS)和在生产中使用 PnP(以提高安装速度)。如果我们仅在启用 PnP 时应用补丁,那么包缓存将变得不同,例如,这将破坏不可变的安装。

¥Which now begs the question: why do we still apply this patch even when Plug'n'Play is disabled? The main reason is that Yarn intends to provide consistent behaviour. Some setups involve using the node_modules linker during development (to avoid having to setup editor SDKS) and PnP in production (for install speed). If we were to only apply the patches when PnP is enabled, then the package cache would turn different, which would for example break immutable installs.

我们可以通过开关使其可配置,但最终我们认为不值得进行额外的配置:

¥We could potentially make it configurable through a switch, but in the end we decided it wasn't worth the extra configuration:

  • 如果未启用 PnP,则 TypeScript 补丁为空操作,因此这不会影响你的工作(如果影响,请打开问题)

    ¥The TypeScript patch is a noop if PnP isn't enabled, so this shouldn't affect your work (if it does, please open an issue)

  • 我们希望有一天最终能在 TypeScript 中实现这个 PR,因此我们能吸引到的关注越多,我们的信心就越高

    ¥We hope to eventually land this PR in TypeScript one day, so the more eyes we can get on it the higher our confidence will be

  • 从 Yarn 3+ 开始,失败的内置补丁将被忽略并回退到原始源

    ¥Since Yarn 3+, failing builtin patches are simply ignored and fallback to the original sources