你提到的 pnpm-workspace(准确来说是 pnpm-workspace.yaml 文件)并不是 pnpm 最近才“凭空发明”的新东西,它已经存在很久了。
但你之所以会有“现在多了一个”或者“突然被频繁提及”的感觉,是因为随着前端工程化的发展,尤其是 pnpm 近期重大版本的更新,这个文件的地位和重要性被极大地提升了。
以下是导致它现在变得如此核心和普遍的 4 个关键原因:
1. 🚀 pnpm v9 引入了重磅特性:Catalogs(依赖目录)
这是最直接的原因。在 pnpm v9 中,官方推出了 Catalogs 功能,专门用于解决 Monorepo(单体仓库)中多个子项目依赖版本不一致的问题。
- 过去:你在每个子项目的
package.json里手动写"react": "^18.2.0",很容易出现版本碎片化。 - 现在:你可以在
pnpm-workspace.yaml中统一定义版本,子项目只需引用catalog:default。 - 关键点:Catalogs 功能只能在
pnpm-workspace.yaml中配置,无法在package.json中实现。这迫使大量新项目必须创建并使用这个文件。
# pnpm-workspace.yaml 示例 (pnpm v9+)
packages:
- 'packages/*'
- 'apps/*'
# 统一定义依赖版本 (Catalogs)
catalog:
react: ^18.2.0
react-dom: ^18.2.0
typescript: ^5.3.02. 📦 Monorepo(单体仓库)架构成为绝对主流
过去,前端项目多是单仓库(Single Repo),一个项目一个 package.json。 现在,无论是开源库(如 Vue, React)、企业级中后台,还是全栈框架(如 Next.js, Nuxt),都倾向于使用 Monorepo(一个仓库包含多个 app 和 package)。
pnpm-workspace.yaml就是 pnpm 管理 Monorepo 的核心配置文件。它告诉 pnpm:“当前目录下哪些文件夹属于同一个工作区,它们可以互相 link(软链接)并共享node_modules”。
3. ⚡ 比 package.json 的 workspaces 更强大、更解耦
npm 和 Yarn 也支持 workspace,但它们通常要求你把配置写在根目录的 package.json 中:
// package.json (npm/yarn 的做法)
{
"name": "my-monorepo",
"workspaces": ["packages/*"]
}pnpm 虽然也兼容这种写法,但官方强烈推荐使用独立的 pnpm-workspace.yaml,原因在于:
-
职责单一:
package.json应该只描述当前包的元数据,而 workspace 是整个仓库的基础设施配置,分离开来更清晰。 -
专属高级配置:
pnpm-workspace.yaml支持一些package.json无法实现的高级 pnpm 专属配置,例如:
peerDependencyRules(处理对等依赖警告)overrides(全局强制覆盖某个依赖的版本,修复安全漏洞) (注:部分 overrides 也可在 package.json,但 workspace 级别的全局控制在 yaml 中更直观)patchedDependencies(全局应用 patch)
4. 🛠️ 现代工具链的“标配”绑定
现在流行的 Monorepo 构建和管理工具,几乎都将 pnpm-workspace.yaml 作为首选或默认的识别标志:
- Turborepo (Vercel 出品):官方文档首推 pnpm +
pnpm-workspace.yaml。 - Nx:完美支持并优先读取该文件。
- Changesets:管理多包版本发布的事实标准,深度依赖 pnpm workspace 结构。
- Rush / Lerna:也都与 pnpm workspace 有良好的集成。
💡 总结:你需要关心它吗?
- 如果你只是开发一个简单的单页应用(SPA)或单个 Node.js 服务:你不需要
pnpm-workspace.yaml。照常使用package.json和pnpm install即可。 - 如果你在搭建一个包含多个子项目(如
apps/web,apps/api,packages/ui,packages/utils)的仓库:你必须在根目录创建pnpm-workspace.yaml。
最简单的创建方式: 在项目根目录运行:
pnpm init -w
# 或者手动创建一个 pnpm-workspace.yaml 文件,写入:
# packages:
# - 'packages/*'
# - 'apps/*'简而言之,不是 pnpm 突然“多”了个东西,而是前端工程化演进到了 Monorepo 时代,而 pnpm-workspace.yaml 正是 pnpm 驾驭这个时代的最强武器。
