如何安全清理 Swift Package Manager 缓存
AskClean 团队 · 更新于 2026-07-31
单个项目的构建产物先用 swift package clean;需要重置该包完整的构建缓存时用 reset;只有共享仓库缓存本身过大或损坏时,才用 swift package purge-cache。Package.swift 和 Package.resolved 定义了依赖,不属于应该随手删除的缓存。

SwiftPM 缓存不止一层
Swift Package Manager 会在不同范围保存不同类型的可再生数据。命令行包通常有一个 .build 目录,里面包括依赖检出、仓库数据、构建产物和工作区状态。SwiftPM 还维护共享仓库缓存,让多个项目不必反复从网络下载同一份依赖。
Xcode 又增加了一层。App 使用 Swift Package 时,包的检出与构建产物通常跟随项目的 DerivedData。因此,同一个依赖如果只在 Xcode 内出问题,处理方法可能与直接运行 swift build 不同。
最安全的原则是:只清理足以解释当前问题的最小范围。一次构建失败,不等于要抹掉全局缓存。项目级清理恢复更快,更可能在离线状态下完成,也不会拖慢其他仓库。
三个 SwiftPM 命令,作用范围完全不同
SwiftPM 官方文档把三个命令的职责分得很清楚。swift package clean 删除当前包的构建产物。遇到旧编译结果、莫名其妙的链接问题,或只想回收某一个仓库的空间时,应先用它。
swift package reset 会重置当前包完整的缓存与构建目录。它比 clean 更彻底,可能让该包的依赖和工作区状态重新准备。只有 clean 没解决本地包工作区损坏或不一致时,才需要升级到 reset。
swift package purge-cache 清理的是 SwiftPM 全局共享的仓库缓存。之后多个项目都可能重新联网获取依赖,首次解析与构建也会变慢。它适合处理确实异常膨胀或损坏的共享缓存,不适合变成每次构建前的固定仪式。
- 先提交或暂存源代码改动,确认 Package.swift 和 Package.resolved 仍在项目应有的位置。
- 进入包根目录,运行 swift package clean,再重试原来的构建。
- 如果包级工作区仍然不一致,运行 swift package reset,然后重新解析和构建。
- 只有确认共享仓库缓存过大或损坏时,才运行 swift package purge-cache。
- 在清理 Xcode DerivedData 前,先核对依赖图和命令行构建是否已经恢复。
命令是否可用取决于当前安装的 Swift 工具链。先运行 swift package --help,确认这台 Mac 支持哪些子命令。
不要把 Package.resolved 当缓存删
Package.resolved 记录的是依赖解析结果,不是下载缓存。对 App 项目来说,把它纳入版本控制,可以让团队成员和 CI 使用一致的依赖版本。删除后,下一次解析可能选中 Package.swift 允许范围内的其他版本。
当你明确想重新解析全部依赖时,删除它可以是一项有意识的排查动作,但这已经改变了实验变量。如果目标只是腾空间或重建产物,就应该保留 Package.resolved,避免一次清缓存悄悄变成依赖升级。
Package.swift 更是源代码,任何缓存清理都不应该删除或随意修改它。同理,Sources、Tests、插件和本地路径依赖也是项目内容。生成的 .build 可以再生,作者写下的文件却未必能够恢复。
清理 Xcode 项目使用的 Swift Package
如果依赖由 Xcode 项目使用,可以先尝试 File > Packages > Reset Package Caches;随后用 File > Packages > Resolve Package Versions,按项目与解析文件重新恢复依赖图。不同 Xcode 版本的菜单名称可能略有差异。
如果问题出在该项目编译后的包产物,删除对应项目的 DerivedData 即可。可以通过 Xcode Settings > Locations 打开位置,再在访达中只处理那一个项目文件夹。下次构建会重新编译 App 和包,并重建索引。
只有一个项目受影响时,不要顺手清空整个 DerivedData 根目录。保留每天活跃项目的热缓存,可以少付很多编译时间。如果 Mac 上装有多套 Xcode,重新解析前先启动真正要使用的版本,让正确的工具链和平台支持参与构建。
先诊断,再清缓存
为了磁盘空间,应该先测量各仓库的 .build 与共享缓存,而不是凭感觉。搜索废弃项目里的 .build,经常比抹掉仍在为活跃项目加速的全局缓存更划算。
为了构建故障,则要先保存原始错误。认证失败、Git 服务不可用、Package manifest 无效、工具链不兼容、校验和变化,都不会因为删掉下载文件而自动修好。过早清缓存还可能抹掉线索,并额外引入一次网络失败。
清理后,用 swift package show-dependencies 或 Xcode 的包依赖图核对解析结果,并运行真正相关的测试。依赖能成功下载,不代表它就与当前工具链、平台或部署目标兼容。
开发机与 CI 应采用不同策略
开发机适合选择性清理:仓库长期不再使用时删掉本地构建产物,只要全局仓库缓存仍在节省下载时间就不必动它。CI 则不同,临时 Runner 可以每次从干净环境开始;长期 Runner 需要明确的体积预算,缓存键还应包含 Swift 工具链与依赖解析状态。
不要在每次构建前运行 purge-cache。那会放弃复用、增加网络依赖,并让限流或上游故障更难受。只有测量显示异常增长、确认缓存完整性有问题,或长期 CI 节点到了受控维护窗口时,才值得清理全局缓存。
故障记录里也要写清范围。「清过 SwiftPM 缓存」含糊不清;「在仓库 A 运行 swift package clean」和「清空全局仓库缓存」的影响面与恢复成本完全不同。
用 AskClean 找到周边的开发者存储
AskClean 可以盘点 SwiftPM 周围的大型开发者存储,包括各项目 Xcode DerivedData、仓库构建产物、npm 等已声明的包缓存、模拟器数据和无法归类的大文件夹,并说明每项是否可重建。
SwiftPM 自身仍应以官方 Swift 命令定义的作用范围为准。AskClean 适合告诉你真正占空间的是哪一类,而不是把精确的包管理操作变成一次解释不清的批量删除。
SwiftPM 命令作用范围
按问题范围与恢复成本选命令,不要默认选择最激进的那个。
| 操作 | 作用范围 | 预期后果 |
|---|---|---|
| swift package clean | 当前包的构建产物 | 下次构建时重新编译。 |
| swift package reset | 当前包的缓存与构建目录 | 包级本地状态需要重新准备。 |
| swift package purge-cache | 全局 SwiftPM 仓库缓存 | 多个项目之后可能需要联网重新获取依赖。 |
| 删除 Package.resolved | 依赖解析状态 | 下次可能解析出其他允许版本;这不是普通缓存清理。 |
常见问题
swift package clean 会删除什么?
它删除当前包的构建产物,不会删除 Package.swift,也不会主动升级依赖要求。下一次构建会重新生成这些内容。
reset 和 purge-cache 有什么区别?
reset 针对当前包的完整缓存和构建目录;purge-cache 针对 SwiftPM 全局共享的仓库缓存。后者会影响多个项目之后的依赖获取。
应该删除 Package.resolved 吗?
普通清理不应该删。它记录已经解析的依赖版本,删除后下次可能选中其他允许版本。只有明确需要重新解析依赖时,才把它作为有意识的操作。
为什么运行 clean 后,Swift Package 还是占很多空间?
剩余内容可能是依赖检出、全局仓库缓存,或者属于 Xcode DerivedData,而不是命令行包的构建产物。先测量每一层,再决定用 reset、purge-cache 还是清理特定项目 DerivedData。
参考来源