## 关于 Yarn 缓存你可能想知道的几件事在 JavaScript 开发的世界里依赖管理是个绕不开的话题。这些年看着 npm、Yarn、pnpm 轮番登场每个工具都在试图解决相似的问题却又带着各自不同的思考。今天想聊聊 Yarn 的缓存机制这可能是它最实用却最容易被忽视的特性之一。缓存究竟是什么简单来说Yarn 缓存就是一个本地仓库里面存放着你曾经下载过的所有包。它不是简单地把下载的压缩包扔在某个文件夹里而是做了一些整理工作。想象一下你经常去图书馆借书。每次借书都要去总馆排队、登记、取书很麻烦。于是你在家里弄了个书架把常看的书、最近借过的书都放上去。下次想再看的时候直接从书架上拿就行不用再跑一趟图书馆。Yarn 缓存就是那个书架。但它的工作方式比书架要聪明些。当你第一次安装某个包时Yarn 会从注册表下载它然后做两件事一是把包解压到项目的 node_modules 目录二是把下载的压缩包保存到缓存目录。这个缓存是按内容寻址的——意思是文件的哈希值决定了它的存储位置。同一个包的不同版本会有不同的哈希值所以都能被妥善保存。缓存能带来什么最直接的好处当然是节省时间。网络请求总是比本地读取慢尤其是当包体积较大或者网络状况不佳时。有了缓存第二次安装同一个版本的包时Yarn 就直接从本地读取速度会快很多。另一个不太明显但很重要的好处是离线工作能力。如果你的网络临时断开或者需要在飞机上、火车上写代码只要之前下载过的包都在缓存里你仍然可以正常安装依赖、创建新项目。这对于经常移动办公的开发者来说很实用。缓存还能减轻注册表的压力。想象一下大型团队里几十个开发者每天都要安装相似的依赖。如果没有本地缓存每个人的每次安装都会向中央服务器发起请求。有了缓存只有第一次安装时需要远程下载后续都从本地获取。这对公司内部搭建的私有注册表尤其重要能显著降低服务器负载。如何使用缓存Yarn 的缓存基本上是自动工作的你不需要特意去配置什么。安装包的时候Yarn 会先检查缓存如果找到了就直接使用找不到再去下载。不过有时候你可能需要手动干预一下。比如你想看看缓存里到底存了些什么可以用yarn cache list命令。这会列出所有缓存的包及其版本信息。如果缓存占用了太多磁盘空间或者你想清理掉一些旧的、不再使用的包可以运行yarn cache clean。不过要谨慎使用这个命令因为清理后下次安装时又需要重新下载可能会比较慢。缓存目录的位置取决于操作系统。在 Linux 和 macOS 上通常在用户主目录的.yarn-cache文件夹里在 Windows 上则在用户目录的AppData\Local\Yarn\Cache。如果你想把缓存移到其他位置比如更大的硬盘分区可以设置YARN_CACHE_FOLDER环境变量。一些实际经验关于缓存的使用有几个细节值得注意。首先是缓存的一致性。Yarn 使用哈希值来验证缓存文件的完整性。如果文件在存储过程中损坏了比如磁盘错误Yarn 能检测到并重新下载。这个机制保证了即使缓存出问题也不会导致项目依赖出错。其次是缓存的共享。在持续集成CI环境中如果多个构建任务需要相同的依赖可以配置它们共享同一个缓存目录。这样第一个任务下载的包后续任务都能直接使用能显著加快构建速度。很多 CI 服务都提供了缓存功能本质上就是把这个目录保存下来供下次构建使用。还有一个细节是关于缓存的更新。当你运行yarn upgrade更新包版本时新版本的包会被下载并添加到缓存但旧版本的包并不会被立即删除。这保证了如果你切换回旧版本比如检出项目的旧提交依赖仍然能快速安装。缓存通常只会在空间不足时或者你手动清理时才会删除旧文件。与其他工具的对比说到缓存难免要和其他包管理器比较一下。npm 也有缓存机制原理和 Yarn 类似。但早期版本的 npm 缓存策略比较保守有时会导致不必要的网络请求。现在的 npm 在这方面已经改进很多不过 Yarn 从一开始就把缓存设计得比较激进默认行为就是尽可能使用缓存。pnpm 采取了不同的思路。它使用一个全局存储所有项目共享同一份依赖文件通过硬链接的方式在项目的 node_modules 中创建引用。这种方式更节省磁盘空间因为同一个版本的包在物理上只存储一份。但它的实现也更复杂依赖文件系统的硬链接功能。Yarn 的缓存策略介于两者之间它不像 pnpm 那样全局共享文件但比传统 npm 更积极地使用缓存。这种平衡让它在大多数场景下都能工作得很好既不会太激进导致问题又能提供明显的性能提升。选择哪种工具往往取决于具体的需求。如果磁盘空间特别紧张pnpm 的方案可能更合适。如果团队已经习惯了 npm 的工作流升级到最新版 npm 也能获得不错的缓存效果。而 Yarn 提供了一个折中的选择既有良好的缓存性能又保持了相对简单的实现。最后一点想法技术工具的设计总是伴随着权衡。缓存机制在提升速度的同时也带来了磁盘空间的占用、一致性的维护等问题。好的工具不是没有缺点而是在特定场景下做出了合适的选择。Yarn 的缓存可能不是最创新的但它确实解决了实际问题。在每天都要安装依赖、构建项目的开发工作中这些看似微小的优化累积起来能节省不少时间。而节省下来的时间可以用来思考更重要的设计问题或者只是喝杯咖啡放松一下。工具终究是为人服务的。了解它们的工作原理不是为了成为工具的专家而是为了让工具更好地为我们工作。缓存是这样其他技术特性也是这样。