# node_modules 无处不在：如何找到、清理并恢复它们

> 找出 Mac 上的每个 node_modules 文件夹及其大小，删除不需要的，按锁文件重新安装，并清理包管理器缓存。

- URL: https://moreroom.app/zh-Hans/learn/node-modules-cleanup
- Published: 2026-10-17
- Updated: 2026-10-17
- Publisher: MoreRoom (Yando Pte. Ltd.) — https://moreroom.app

## TL;DR

- 只要保留 package.json 和锁文件，删除 node_modules 就是安全的；npm ci 或 pnpm install 会装回完全相同的版本。
- 带 -prune 的 find 命令可以列出个人文件夹中的每个 node_modules 文件夹及其大小，且不会深入嵌套的文件夹。
- npx npkill 让你以交互方式浏览并删除 node_modules 文件夹，但它会立即删除，不经过废纸篓。
- 使用 pnpm 时，node_modules 中的文件是共享存储的克隆或硬链接，所以在运行 pnpm store prune 之前，删除它们释放不了多少空间。
- .next、.turbo、.nuxt、.svelte-kit 和 .parcel-cache 等构建文件夹会自动重建，同样可以放心移除。

[node_modules](https://moreroom.app/glossary#node-modules) 文件夹保存着为某个 JavaScript 或 TypeScript 项目安装的依赖，一个典型的 node_modules 有几百 MB。旧项目一多，它们很容易累积到几十 GB。**只要保留 `package.json` 和锁文件，它们就可以放心删除**：当你回到项目时，包管理器会重新安装相同的版本。

## 找出每个 node_modules 文件夹及其大小

这条命令会搜索你的个人文件夹，跳过 `~/Library` 和废纸篓，列出每个 `node_modules` 文件夹及其大小，最大的排在最后：

```sh
find ~ \( -path "$HOME/Library" -o -path "$HOME/.Trash" \) -prune -o -type d -name node_modules -prune -print0 2>/dev/null | xargs -0 du -sh 2>/dev/null | sort -h
```

原理是这样的：第一个 `-prune` 跳过两个排除的文件夹，`-type d -name node_modules` 匹配目标文件夹，第二个 `-prune` 阻止 `find` 深入其中，因此嵌套的 `node_modules` 只会在其上层文件夹中计算一次。`du -sh` 测量每个文件夹的大小，`sort -h` 给列表排序。这条命令只读取。个人文件夹很大时，可能需要几分钟，“终端”也可能请求访问“文稿”、“桌面”或“下载”。

位于 `~/.nvm`、`~/.vscode` 或 `~/.cursor` 等工具文件夹中的结果可以忽略。它们属于已安装的工具和编辑器扩展，而不是你的项目。

如果你的项目使用 pnpm，显示的大小会比实际能收回的空间大。原因见下文。

## 删除不需要的文件夹

删除之前，打开项目文件夹，确认其中有锁文件：`package-lock.json`（npm）、`pnpm-lock.yaml`（pnpm）、`yarn.lock`（Yarn）或 `bun.lock` / `bun.lockb`（Bun）。保留它，也保留 `package.json`。

最安全的删除方法是在访达中把 `node_modules` 拖到废纸篓。在清倒废纸篓之前，你仍然可以反悔。小文件很多时，移到废纸篓需要一点时间。

在“终端”中，进入某个项目文件夹后：

```sh
cd ~/Projects/old-app
rm -rf node_modules
```

`rm -rf` 会永久删除，不经过废纸篓。请先用 `pwd` 确认当前所在的文件夹，并且绝不要搭配通配符或空变量运行它。

### npkill：交互式的替代方案

[npkill](https://github.com/voidcosmos/npkill) 会列出 `node_modules` 文件夹及其大小，让你按一下键就删除一个：

```sh
npx npkill -d ~/Projects
```

`-d` 用于设置搜索的起点；不加的话，npkill 从当前文件夹开始。用方向键移动，按空格键或 Del 键删除所选文件夹。npkill 会立即删除，不经过废纸篓。它会用 ⚠️ 标出 App 运行所需的文件夹，这些应当保持原样。如果想先试试，可以用 `--dry-run` 模拟删除。

## 回到项目时重新安装

使用严格按照锁文件安装的命令：

| 包管理器 | 锁文件 | 重新安装 |
|---|---|---|
| npm | `package-lock.json` | `npm ci` |
| pnpm | `pnpm-lock.yaml` | `pnpm install --frozen-lockfile` |
| Yarn（Berry） | `yarn.lock` | `yarn install --immutable` |
| Yarn Classic | `yarn.lock` | `yarn install --frozen-lockfile` |
| Bun | `bun.lock` | `bun install --frozen-lockfile` |

[`npm ci`](https://docs.npmjs.com/cli/v11/commands/npm-ci) 要求有锁文件，会先移除已有的 `node_modules`，并且从不更改 `package.json` 或锁文件。普通的 `npm install` 也可以，但可能会更新锁文件。

## 其他会自动重建的文件夹

框架和构建工具会在 `node_modules` 旁边存放缓存和输出。在你没有运行的项目中，这些文件夹可以放心删除；下一次构建或启动开发服务器时会重新创建。

| 文件夹 | 创建者 |
|---|---|
| `.next` | Next.js |
| `.nuxt` | Nuxt |
| `.svelte-kit` | SvelteKit |
| `.turbo` | Turborepo |
| `.parcel-cache` | Parcel |
| `.angular` | Angular CLI |

`dist` 和 `build` 通常也是构建输出，但名称太常见。有些项目会把文件提交到这里，或另作他用，所以删除前请先看看里面的内容。

列出某个项目文件夹中的框架缓存：

```sh
find ~/Projects -type d \( -name .next -o -name .nuxt -o -name .svelte-kit -o -name .turbo -o -name .parcel-cache \) -prune -print0 | xargs -0 du -sh | sort -h
```

## 清理全局包缓存

每个包管理器还有一个由所有项目共享的下载缓存。清除它是永久性的，但没有坏处：需要时包会重新下载。

```sh
npm cache clean --force
pnpm store prune
yarn cache clean
bun pm cache rm
```

- **npm** 的缓存位于 `~/.npm/_cacache`。[npm 缓存文档](https://docs.npmjs.com/cli/v11/commands/npm-cache)解释了为什么 `clean` 需要 `--force`，并指出 `npm cache verify` 可以做垃圾回收而不清空全部内容。`npx` 获取的包位于 `~/.npm/_npx`。
- **pnpm** 在 macOS 上把存储放在 `~/Library/pnpm/store`（`pnpm store path` 会显示你的位置）。[`pnpm store prune`](https://pnpm.io/cli/store) 只移除没有任何项目引用的包，pnpm 文档建议偶尔运行，而不是频繁运行。
- **Yarn Classic** 的缓存位于 `~/Library/Caches/Yarn`。对于 Yarn Berry，`yarn cache clean --mirror` 会清空 `~/.yarn/berry/cache` 中的全局缓存。
- **Bun** 的缓存位于 `~/.bun/install/cache`；`bun pm cache rm` 会把它清空。

用 nvm 安装的旧版 Node.js 也会在 `~/.nvm/versions/node` 中累积；`nvm uninstall <version>` 可以移除不再需要的版本。

## 为什么 pnpm 释放的空间比 du 显示的少

npm 和 Yarn Classic 会把每个包拷贝到每个项目的 `node_modules` 中。pnpm 则把每个包只在[内容寻址存储](https://pnpm.io/motivation)中保存一份，再把文件链接到每个使用它的项目中。在 macOS 上，pnpm 默认的 [`packageImportMethod`](https://pnpm.io/settings/node-modules) 会先尝试 APFS 克隆，再尝试[硬链接](https://moreroom.app/glossary#hard-link)。

![npm 把包拷贝到每个项目中，而 pnpm 通过克隆或硬链接共享同一个存储](https://moreroom.app/learn/img/node-modules-cleanup-pnpm-store.svg)

无论哪种方式，数据都是共享的。`du` 仍会在每个项目中计入完整大小，所以删除 pnpm 项目的 `node_modules`，释放的空间通常远少于报告的数字。等到 `pnpm store prune` 移除剩余项目都不再使用的包时，空间才会回来。要做到这一点，存储必须和项目位于同一个磁盘上；外置驱动器上的项目会在那里拥有自己的存储。

## MoreRoom 能帮你做什么

MoreRoom 免费版会找出有锁文件且 30 天未改动的项目中的 `node_modules` 文件夹，以及 `.next` 和 `.turbo` 等框架缓存，并标注为“可安全移除”。它会跳过 `~/Library` 以及 `~/.nvm`、`~/.vscode` 这类工具文件夹。你可以逐项把它们移到废纸篓，并且可以撤销。对于 npm 缓存和 pnpm 存储，MoreRoom 会运行 `npm cache clean --force` 和 `pnpm store prune`；这些命令是永久性的，并会明确标注。

MoreRoom Pro 还提供项目休眠：不活跃的项目会丢弃 `node_modules` 和构建输出等可重建的文件夹，回到项目时点一下即可唤醒。Pro 还包括“收集器”和目标模式。

## FAQ

### 删除 node_modules 安全吗？

安全。它只包含已安装的依赖，包管理器可以根据 package.json 和锁文件重新安装。只删除你当前没有在运行的项目中的 node_modules，并保留锁文件。

### package-lock.json 也要删除吗？

不要。锁文件记录了可以正常运行的确切版本。保留它，以后 npm ci、pnpm install 或 yarn install 才能重建出相同的 node_modules。

### 为什么删除 pnpm 项目的 node_modules 释放的空间这么少？

pnpm 在共享存储中为每个包只保留一份，再把这些文件克隆或硬链接到每个项目中。删除某个项目的 node_modules 只会移除链接；之后运行 pnpm store prune，才会删除没有任何项目使用的包。

### npm cache clean --force 安全吗？

安全。它会清空 ~/.npm/_cacache 中的 npm 下载缓存，需要时 npm 会重新下载包。npm 文档指出，清除缓存唯一的用处就是回收磁盘空间。

### npkill 会把文件夹移到废纸篓吗？

不会。npkill 会立即删除所选文件夹。可以先用它的 --dry-run 选项演练一遍；如果想要废纸篓这层保障，请使用访达。
