Monorepo 需要什么(真实需求)

发布: (2026年2月25日 GMT+8 23:35)
4 分钟阅读
原文: Dev.to

Source: Dev.to

Monorepo 包管理器应该处理的内容

  • 工作区(多个 package/app)
  • 大型仓库的快速安装
  • 确定性的 lockfile(在所有地方使用相同的依赖)
  • 良好的 CI 缓存
  • 最小化“依赖怪异”(幽灵依赖、提升意外)
  • 流畅的开发者工作流(跨 package 运行脚本、过滤等)

pnpm 的优势

全局内容可寻址存储

  • pnpm 在全局存储中为每个包的每个版本只保留一份副本。
  • 每个项目通过硬链接指向 node_modules
  • 结果: 重复安装非常快,庞大的 monorepo 能受益良多。

更小的仓库体积

  • 使用 npm 时,每个工作区可能在子项目之间重复相同的包。
  • 使用 pnpm 时,包会从全局存储复用。
  • 结果: 仓库体积更小,Docker/CI 层构建更快。

严格的依赖处理

  • 包不能导入未在自身 package.json 中声明的依赖。
  • 这可以防止经典的 monorepo bug:“在我机器上能跑是因为被提升了…但 CI 后来就坏了。”

人性化的工作区命令

  • 在所有 package 中运行脚本。
  • 过滤后仅在受影响的 package 上运行。
  • 递归的清理安装/构建。

高效的缓存

  • 由于 pnpm 的存储可复用,缓存更简单、更有效。
  • 在许多 CI 流水线中,pnpm 安装在第一次缓存后会始终保持更快。

npm 的考虑因素

  • npm 默认随 Node 一起提供。
  • 一些旧工具和脚本假设 npm 的提升行为,使得在某些企业环境中 npm 显得“乏味且安全”。
  • 如果团队已经熟悉 npm,且仓库规模较小,npm 工作区可能已经“够用了”。
  • npm 经常提升依赖,允许代码导入未声明的包,这会把缺失依赖的问题隐藏到后期才显现。

在 pnpm 与 npm 之间的选择

方面npmpnpm
依赖处理提升的依赖即使未声明也可能可用通过符号链接结构强制正确性;未声明的依赖会提前被捕获
仓库体积由于重复的包而更大由于共享存储而更小
安装速度对大型仓库尤其是重复安装时较慢更快,特别是在第一次缓存之后
适用场景小型仓库、依赖提升的环境大型仓库、重复安装、重视严格性的团队

如果你想要:

  • 大型 monorepo 的更快、确定性的安装
  • 严格的依赖强制
  • 更好的 CI 缓存

请选择 pnpm。

如果你想要:

  • 与期望提升行为的旧工具兼容
  • 小型仓库的简易性

请选择 npm。

推荐的 pnpm 设置

  • 在仓库根目录保留单一的 pnpm-lock.yaml
  • 使用 pnpm 工作区。
  • 为了团队一致性,固定 pnpm 版本,例如:
{
  "packageManager": "pnpm@9.1.2"
}
  • pnpm-workspace.yaml 中定义工作区布局:
packages:
  - "apps/*"
  - "packages/*"

我在 2026 年的默认选择: 几乎所有新 monorepo 都使用 pnpm。

0 浏览
Back to Blog

相关文章

阅读更多 »

使用 Postgres 的视频会议

昨天在 X 上,SpacetimeDB 发推文称他们实现了“世界上第一个基于数据库的视频通话”,并以自己的方式邀请其他人尝试。