跳到主要内容
Mole
功能 实测 口碑 定价 常见问题 博客
EnglishEN 简体中文中 繁體中文繁 日本語日 한국어한 FrançaisFR DeutschDE ItalianoIT EspañolES
立即购买购买 下载

    帮助、文档、更新日志和文章

    首页/博客

    npm 缓存越用越大,Mole 这次只清不再被引用的部分

    开发者清理发布于 2026年10月5日约 4 分钟

    最近有用户提到,用 Mole 维护完 Mac,npm 的缓存还在,自己清理以后从 8 GB 变成了 2 GB。这条反馈让我重新看了一遍开发工具的缓存,哪些东西还能用,哪些已经没有引用,还有哪些工具自己就在清,Mole 再清一次反而让下一次构建多花时间。

    这次调研和改动发生在 10 月 5 日,代码已经补上,会随后续版本交付,当前已发布的 Preview 包还没有带上,下面写的是这次开发过程中的实测和取舍。

    npm 的缓存为什么会越用越大

    npm 默认把缓存放在 ~/.npm/_cacache,里面有两部分,content-v2 保存软件包和软件源返回的内容,index-v5 记录从哪个请求能找到哪份内容,文件按内容的哈希命名,同一份内容可以被多个索引条目引用。

    软件包的信息更新后,新内容会被写进去,旧索引条目在后续查询时可能被整理掉,旧文件却还留着,时间一长,就积累出一批已经没有索引指向的文件。npm 的文档也说明,缓存不会自行清理,会随着安装继续增长。

    不过那位用户已经清过自己的缓存,我没拿到清理前的副本,也不能确认他具体跑了哪个命令,所以 8 GB 降到 2 GB 是这次调查的起点,不能当成 Mole 已经清出了 6 GB,更不能说这 6 GB 全是没有引用的内容。

    副本实验里,verify 也删掉了仍然能用的内容

    这次实验用的是本机缓存的副本,npm 11.19.1、cacache 20.0.4,原缓存没有改动,它刚建立约一天,里面的内容文件一共 309796162 字节,还不是一份积累了几个月的缓存。

    判定方式 内容文件数 内容字节数
    没有任何有效索引条目引用 1 614295
    npm cache verify 实际删除 6 25469972

    差别来自 cacache 的 verify 实现,它清理内容、校验完整性,再重建索引,同一个 key 只保留最后一条,旧条目里却可能还有不同请求需要的完整元数据和精简元数据,这两种内容不能简单当成一份的旧版本。

    在副本上,verify 删除的内容里有 11199796 字节仍被有效的另一种请求条目引用,清理前能离线读取的几个软件包信息,清理后再跑离线 npm view 就报了 ENOTCACHED,联网以后可以重新获取,但这已经改变了缓存原来能做的事。

    所以这里选了更窄的判定,只要任何一条有效索引还引用着它,就留着,哪怕这次只能找到约 0.6 MB,也不为了接近 verify 的数字去删另一种请求仍然需要的内容。

    放进清理页,保留整个缓存的选择

    Mole 的新实现只扫描默认的 ~/.npm/_cacache,没有引用、超过一天的内容会合成一行,放在清理页的开发工具分组里,默认勾选,整个 npm 缓存仍然需要自己确认,两种选择重叠的部分也只计算一次。

    扫描时遇到 npm install、npm ci 这类正在写缓存的命令就先不处理,读不清索引也不列出来,删除前还会重新确认引用,索引文件和临时目录都不改,Mole 也不会在后台调用 npm 的清理命令。

    这里保留的是索引仍然指向的内容,不等于保证每一个项目永远能离线构建,锁文件还可能按哈希直接找某个软件包,私有软件源和旧版本也未必始终能重新下载,源码、锁文件和需要保留的产物仍然要单独保存。如果配置了别的 npm 缓存路径,这一轮也没有覆盖。

    Go、Cargo 和 pnpm,不能照着 npm 再做一遍

    顺着这条反馈,又看了其他工具。Go 本来就会自动整理构建缓存,实现里保留最近五天用过的条目,再留一小时的时间余量,也就是 121 小时,Mole 以前把整个构建缓存目录列进默认清理,这次改成同样的时间规则,最近还要用的条目留下来,不用在下一次构建时全部重新编译。

    Cargo 已经有自动缓存回收,这次样本里没有到期内容,之前清掉从软件包仓库解压出的源码,约 29 小时后又下载了约 157 MB、解压出约 1.06 GB,所以这次没有再做一份 Cargo 自动回收,原来需要自己确认的清理项仍然保留。

    pnpm 的共享存储又不同,调研里的 APFS 样本不能靠硬链接数量证明文件已经没人用,照搬这个判据会把整份存储都选出来,所以这次没有加一份 pnpm 清理,把一个工具的判定搬到另一个工具上,先得确认它说的使用关系在本机文件系统里仍然成立。

    全局工具和旧 Xcode 项目里的构建产物

    调研时,全局安装的 pake-cli 里面有一个 src-tauri/target,约 1.48 GiB,是它构建 Tauri 时留下的 Rust 产物,并不是 npm 下载缓存。现在这种由工具写下有效 CACHEDIR.TAG 标记的构建目录,也会作为待确认项列出来,工具本身和它的 node_modules 依赖不会跟着删,Rust 构建还在运行时也先留着。

    Xcode 那边还找到 24 份原项目路径已经不存在的 DerivedData,调研时约 9 GiB,这次只有启动磁盘上的项目能确认已经删掉、Xcode 至少两周没有使用过对应缓存,才会列出整个目录,外接盘没接上、没有读取权限,都不能算作项目不存在。这两个大小是当时找到的内容,不是承诺每台 Mac 都能释放这么多,清掉以后再需要构建,仍然要花时间重新生成。

    自己处理时,先确认正在清哪一层

    想看自己的 npm 缓存在哪,可以先运行下面这个只读命令,自定义路径会由 npm 自己报告。

    npm config get cache
    

    确认没有安装和构建正在写这份缓存,再决定是否运行 npm cache verify,它会实际修改缓存,不只是查看,项目的 node_modules 和全局安装的命令又是另外两层,不会被这个命令一起处理,完整的整理顺序可以接着看开发工具缓存清理。

    开发工具越用越占空间,可以用 Mole 清理缓存、查找大文件。

    下载试用 Mole

    继续阅读

    • 开发者清理如何清理开发工具缓存,又不破坏构建约 3 分钟
    • 开发者清理Mac 上的 JetBrains 缓存(IntelliJ、WebStorm、PyCharm)约 4 分钟
    • 开发者清理如何清理 Mac 上的旧 iOS 模拟器运行时约 3 分钟

    Mole · 鼴

    清理 Mac,管理软件,查看运行状态

    v1.16.0 (301) · 更新日志

    产品

    Mac 清理 App 卸载 Mac 优化 磁盘分析 系统监控

    支持

    帮助 功能文档 更新日志 博客

    法律

    服务条款 隐私政策 退款政策

    资源

    命令行工具 推广联盟

    联系

    Twitter hi@mole.fit

    Mole 唯一官网 mole.fit · 请勿下载来源不明的安装包

    命令行版继续免费开源。