
如果你同时维护多个前端项目,node_modules 很快就会变成磁盘空间的黑洞。一个 React、Next.js、Vite 或小程序项目往往几百 MB 起步,多个项目重复安装相同依赖时,浪费会非常明显。
pnpm 的优势就在这里:它不会把同一个版本的包在每个项目里重复存一份,而是把包放进全局内容寻址存储,再通过链接的方式让各个项目复用。结果是安装更快、磁盘占用更低,依赖关系也更严格。
为什么选择 pnpm
传统 npm 或旧版 yarn 的安装方式更接近“每个项目各存一份依赖”:
project-a/node_modules/react <- 一份
project-b/node_modules/react <- 又一份
project-c/node_modules/react <- 再一份
pnpm 则会把相同版本的包集中放在全局 store 中:
~/.pnpm-store/react@18.x <- 全局只存一份
project-a/node_modules <- 链接到 store
project-b/node_modules <- 链接到 store
project-c/node_modules <- 链接到 store
对日常开发来说,这带来三个直接收益:
- 节省磁盘空间:多个项目共享同一份依赖内容,尤其适合 MacBook 本地同时放很多项目的场景。
- 安装速度更快:已经下载过的包可以直接从本地 store 复用。
- 依赖更可控:pnpm 默认不会让项目随意访问未声明的依赖,可以更早暴露“幽灵依赖”问题。
在 Mac 上安装 pnpm
如果你已经使用 Homebrew,推荐直接通过 Homebrew 安装,工具链更统一:
brew install pnpm
安装后验证版本:
pnpm --version
如果你希望把 pnpm 的全局 store 放到指定磁盘,比如外置 SSD,可以配置 store-dir:
pnpm config set store-dir /Volumes/your-disk/pnpm-store
普通用户不一定需要修改这个位置。默认配置已经足够好,只有在本机项目很多、内置硬盘空间紧张,或者希望统一管理开发缓存时,才建议单独设置。
npm 与 pnpm 命令对照
| 场景 | npm | pnpm |
|---|---|---|
| 安装所有依赖 | npm install |
pnpm install |
| 添加生产依赖 | npm install react |
pnpm add react |
| 添加开发依赖 | npm install -D eslint |
pnpm add -D eslint |
| 全局安装工具 | npm install -g xxx |
pnpm add -g xxx |
| 删除依赖 | npm uninstall xxx |
pnpm remove xxx |
| 运行脚本 | npm run dev |
pnpm dev |
| 执行临时工具 | npx create-next-app |
pnpm dlx create-next-app |
| 查看依赖树 | npm ls |
pnpm list |
| 检查过期包 | npm outdated |
pnpm outdated |
| 升级依赖 | npm update |
pnpm update |
| 清理 store | npm cache clean |
pnpm store prune |
多数脚本可以省略 run,例如:
pnpm dev
pnpm build
pnpm lint
如果脚本名和 pnpm 内置命令冲突,再使用完整写法:
pnpm run test
把现有项目迁移到 pnpm
已有项目从 npm 或 yarn 切换到 pnpm,建议按三步走。
第一步,删除旧的依赖目录和锁文件:
rm -rf node_modules
rm -f package-lock.json yarn.lock
第二步,重新安装依赖:
pnpm install
这一步会生成新的 pnpm-lock.yaml。
第三步,验证项目能否正常启动和构建:
pnpm dev
pnpm build
如果项目比较大,不建议直接在主分支迁移。更稳妥的方式是先开一个分支:
git checkout -b feat/migrate-to-pnpm
rm -rf node_modules package-lock.json yarn.lock
pnpm install
pnpm dev
pnpm build
确认开发、构建、测试、部署流程都没问题后,再合并迁移。
哪些项目适合优先迁移
并不是所有项目都需要立刻换成 pnpm。可以按风险和收益排序:
| 项目类型 | 建议时机 | 原因 |
|---|---|---|
| 新项目 | 直接使用 | 没有历史锁文件和 CI 兼容问题 |
| 依赖较多的开发中项目 | 优先迁移 | 节省空间和安装时间的收益明显 |
| 内部工具、管理后台 | 适合迁移 | 通常可控,验证成本较低 |
| 接近交付的项目 | 暂缓 | 稳定优先,避免临近上线引入变量 |
| SSR 或 3D 依赖复杂的项目 | 分支测试 | 重点验证构建、动态导入和部署环境 |
迁移包管理器本身不是业务功能。如果项目正在赶交付,应该等下一个迭代周期再做。
常见问题与解决方案
某些包找不到
pnpm 的 node_modules 不是传统扁平结构。规范的包应该声明自己用到的依赖,但有些旧包或配置不完整的工具会偷偷依赖项目根目录里的包,这就是常说的“幽灵依赖”。
如果遇到这类兼容问题,可以先在项目根目录添加 .npmrc:
shamefully-hoist=true
它会让 pnpm 的依赖提升行为更接近 npm,兼容性更好。代价是依赖隔离没有默认模式那么严格。建议把它作为兼容方案,而不是所有项目的默认选择。
小程序工具链不识别依赖
微信小程序或其他小程序项目经常有自己的依赖构建流程。使用 pnpm 安装后,如果开发者工具里依赖不可用,可以先重新安装:
pnpm install
然后在开发者工具中重新执行“构建 npm”。如果工具链对符号链接支持不好,再考虑使用 shamefully-hoist=true 或保留 npm。
AI 编程助手误用 npm
如果你使用 Claude Code、Codex 或其他 AI 编程助手,建议在项目说明文件里写清楚包管理器,避免它自动执行 npm install 并生成 package-lock.json。
可以在 README.md、CONTEXT.md 或项目约定文档中加入:
## 开发约定
- 包管理器:pnpm
- 安装依赖:pnpm install
- 添加依赖:pnpm add <package>
- 不要使用 npm install,也不要提交 package-lock.json
pnpm-lock.yaml 冲突
多人协作时,pnpm-lock.yaml 也可能产生冲突。锁文件不适合手动大段编辑,最稳妥的方式通常是选择一方版本后重新安装。
例如保留当前分支的锁文件,再重新解析:
git checkout HEAD -- pnpm-lock.yaml
pnpm install
如果你是在合并目标分支,也可以选择目标分支版本,然后重新执行 pnpm install。关键点是:让 pnpm 重新生成一致的依赖解析结果,而不是手改 YAML。
Next.js 项目的迁移检查清单
Next.js、Three.js、GSAP、Howler.js 这类组合对 SSR、浏览器 API 和构建环境更敏感。迁移前建议单独验证:
git checkout -b feat/migrate-to-pnpm
rm -rf node_modules package-lock.json yarn.lock
pnpm install
pnpm list next react react-dom
pnpm dev
pnpm build
如果项目里有只能在浏览器运行的库,继续保留原来的 SSR 安全写法,例如 next/dynamic 配合 ssr: false。换包管理器不会自动解决 SSR 问题,它只改变依赖安装和解析方式。
实用进阶命令
查看某个包为什么被安装:
pnpm why react
只安装生产依赖,常用于部署环境:
pnpm install --prod
交互式升级依赖:
pnpm update --interactive
检查 store 状态:
pnpm store status
清理不再被任何项目使用的 store 内容:
pnpm store prune
什么时候使用 pnpm Workspace
如果你后续把多个前端应用、组件库、设计 token、脚本工具放进同一个仓库,pnpm workspace 会很有用。
典型结构如下:
project/
├── pnpm-workspace.yaml
├── apps/
│ ├── web/
│ └── admin/
└── packages/
├── ui/
└── config/
在根目录创建 pnpm-workspace.yaml:
packages:
- 'apps/*'
- 'packages/*'
Workspace 适合 monorepo,但不适合为了“看起来高级”而提前引入。如果当前只有一个应用,普通 pnpm 项目就够了。等多个应用之间真的需要共享组件、配置或工具包时,再升级到 workspace。
阶段建议
如果你还没在生产项目里用过 pnpm,可以按这个节奏推进:
现在 -> 找一个开发中但风险较低的项目迁移
本周 -> 熟悉 pnpm add、pnpm dev、pnpm why 等常用命令
下次迭代 -> 在更核心的项目里分支测试迁移
将来 -> 多项目共享代码时,再考虑 pnpm workspace
一句话总结:pnpm 很适合多项目开发者,但迁移时不要只看安装成功。真正需要验证的是开发、构建、测试、部署四个环节是否全部跑通。
订阅 FreeMac
每周精选:免费 Mac 软件评测、可信来源更新、替代方案和少折腾指南。