FE-08-包管理与 monorepo:pnpm、yarn、workspaces
本节目标:掌握现代包管理器(pnpm)的优势,理解 monorepo 模式,能用 pnpm workspaces 搭建多包项目。
1. 包管理器演进
1 | 2009 npm(Node 官方) |
2. npm 的痛点
phantom dependencies(幽灵依赖):
1 | my-project/ |
node_modules 嵌套地狱:
1 | my-project/node_modules/ |
磁盘浪费:100 个项目 × 100 个相同依赖 = 1 万份副本。
3. pnpm 优势
3.1 硬链接 + 软链接
1 | ~/.local/share/pnpm/store/ ← 真实存储(每个版本只一份) |
好处:
- 快:硬链接是文件系统操作,几乎零成本
- 省空间:所有项目共享 store
- 无幽灵依赖:只有
dependencies里声明的包才能 import
3.2 安装速度对比
1 | 小项目(~100 包): |
3.3 常用命令
1 | # 安装 |
4. workspace(monorepo)
monorepo = 一个仓库管理多个项目。
4.1 优势
- 共享代码、类型、配置
- 统一依赖管理
- 一次 PR 改多个包,原子提交
- 跨包重构容易
4.2 pnpm workspace 配置
1 | my-monorepo/ |
1 | # pnpm-workspace.yaml |
1 | // 根 package.json |
4.3 共享依赖
1 | // packages/ui/package.json |
workspace 协议:
"workspace:*":用 workspace 里的最新版本"workspace:^1.0.0":匹配版本"workspace:1.0.0":固定版本
4.4 共享配置
1 | // tooling/tsconfig/base.json |
4.5 Changesets(版本管理)
1 | pnpm add -Dw @changesets/cli |
1 | # 改了代码后 |
1 | # 发版时 |
5. Turborepo(增量构建)
痛点:monorepo 里改了一个包,要重新构建所有依赖它的包。
Turborepo 缓存构建结果,只重做必要的:
1 | // turbo.json |
1 | turbo run build # 智能构建(用缓存) |
6. 实战:搭建 monorepo
6.1 初始化
1 | mkdir my-monorepo && cd my-monorepo |
6.2 workspace 配置
1 | # pnpm-workspace.yaml |
6.3 创建子包
1 | # UI 组件库 |
1 | # 主应用 |
6.4 引用 workspace 包
1 | // apps/web/src/main.tsx |
7. pnpm vs npm vs yarn 选型
| 特性 | npm | yarn | pnpm | bun |
|---|---|---|---|---|
| 速度 | 慢 | 中 | 快 | 最快 |
| 磁盘占用 | 大 | 中 | 小(store) | 小 |
| 严格依赖 | ❌ | ❌ | ✅ | ✅ |
| monorepo | workspaces | workspaces | workspaces | workspaces |
| 稳定性 | ✅ | ✅ | ✅ | ⚠️ 新 |
| Node 兼容 | ✅ | ✅ | ✅ | 部分 |
2026 推荐:
- 新项目:
pnpm(默认) - 脚本/工具:
bun(如可接受新生态) - 现有项目:保持现状
8. 依赖管理最佳实践
1. 固定版本还是浮动版本:
1 | // 严格(推荐生产) |
2. 区分 dependencies / devDependencies / peerDependencies:
dependencies:运行时必需devDependencies:开发/构建时peerDependencies:库专用,让使用方装
3. lock 文件:永远提交 pnpm-lock.yaml!
4. 漏洞扫描:
1 | pnpm audit |
5. License 检查:
1 | npx license-checker --summary |
9. CI/CD 缓存
1 | # GitHub Actions |
10. 常见问题
Q: pnpm install 失败 ERR_PNPM_PEER_DEP_ISSUES
A: 加 --no-strict-peer-dependencies 或修复 peer dep 声明。
Q: workspace 包找不到
A: 检查 pnpm-workspace.yaml 路径 pattern;运行 pnpm install 重新链接。
Q: 幽灵依赖(用了未声明的包)
A: pnpm 默认严格,如果一定要用,添加到 package.json 或用 .npmrc 的 shamefully-hoist=true(不推荐)。
Q: lock 文件冲突
A: pnpm install --no-frozen-lockfile 更新,或手动 merge。
小结
| 工具 | 选型建议 |
|---|---|
| pnpm | 新项目首选,速度快、严格、磁盘省 |
| npm | 保守选择,最稳定 |
| yarn | 现有 yarn 项目保持 |
| bun | 工具/脚本,性能极致 |
| pnpm workspaces | monorepo 首选 |
| Turborepo | 增量构建、缓存 |
| Changesets | 版本管理 + Changelog |
核心原则:
- 永远提交
pnpm-lock.yaml - workspace 包用
workspace:*协议 - CI 缓存 store 目录
- peerDependencies 正确声明
- 定期
pnpm audit修漏洞
下一节讲 React 高级:Hooks 原理、并发渲染、Server Components。
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/09/24/FE-08-包管理与monorepo/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!