1. PNPM Workspace 与 Monorepo 详解
约 984 字大约 3 分钟
2025-06-14
一、什么是 Monorepo?
Monorepo (单一代码库)是一种项目管理方式,将多个相关项目放在同一个代码仓库中管理,具有以下优势:
- 可以提取公共代码作为公共包,在项目之间共享。
- 统一管理所有项目的依赖
- 跨项目变更更加方便
- 统一代码风格和构建流程
- 一次修改,可以更新所有关联代码
二、PNPM Workspace
pnpm workspace
是 pnpm 提供的 Monorepo
(单体仓库)管理方案,允许在单个代码仓库中管理多个项目(包),并高效共享依赖。相比 npm/yarn workspace
,pnpm 通过 硬链接 节省磁盘空间,依赖管理更高效。
- Workspace(工作区):一个包含多个子项目的根目录,通过
pnpm-workspace.yaml
定义。 - 共享依赖:所有子项目共用
node_modules
,避免重复安装。 - 依赖提升:将共用的依赖提升到根目录的
node_modules
,减少冗余。 - 跨项目引用:子项目之间可以通过
workspace:*
引用,无需指定版本号。
三、配置一个 Monorepo 项目
1. 初始化项目结构
典型的 monorepo 结构:
my-monorepo
package.json
pnpm-workspace.yaml# 工作空间配置文件
packages# 抽离的公共组件、公共方法
ui# 子项目 1
package.json
utils# 子项目 2
package.json
apps# 具体的项目
web# 应用 1
package.json
2. 配置 pnpm-workspace.yaml
packages:
# 所有在 packages/ 和 apps/ 下的子目录都是工作区包
- "packages/**"
- "apps/**"
# 排除特定目录
- "!**/test/**"
3. 根目录 package.json
{
"name": "my-monorepo",
"private": true, // 私有属性,防止直接安装
"scripts": {
"build": "pnpm -r run build", // -r 表示递归执行所有子项目
"test": "pnpm -r run test"
}
}
四、核心功能与使用
1. 安装所有工作区依赖
# 安装所有工作区项目的依赖
pnpm install
# 等价于
pnpm multi install
2. 添加依赖到特定工作区
# 为 packages/ui 添加 lodash 依赖
pnpm add lodash --filter ui
# 添加工作区的 util 包作为 web 的依赖
pnpm add util --filter web --workspace
3. 运行工作区命令
# 在所有工作区运行 build 命令
pnpm -r run build
# 在特定工作区运行命令
pnpm --filter ui run dev
# 并行运行命令
pnpm -r --parallel run dev
4. 依赖管理特性
- 提升(Hoisting):默认将依赖提升到根 node_modules
- 严格模式:防止非法访问未声明的依赖
- 交叉链接:工作区包相互引用使用符号链接
五、高级用法
1. 工作区协议(workspace:)
在 package.json 中引用工作区内其他包:
{
"dependencies": {
"shared-utils": "workspace:^1.0.0",
"ui-components": "workspace:*" # 总是使用最新版本
}
}
2. 选择性安装
# 只在特定工作区安装指定依赖
pnpm install dependencies --filter workspace_name
3. 发布管理
使用 changesets
进行版本管理和发布:
# 安装 changesets
pnpm add -Dw @changesets/cli
# 初始化
pnpm changeset init
# 添加变更
pnpm changeset
# 版本升级和发布
pnpm changeset version
pnpm publish -r
4. 任务管道
# 按照拓扑顺序构建 (先构建依赖项)
pnpm --recursive --filter=... run build
六、最佳实践
- 统一版本:使用
workspace:*
保持工作区内包版本同步 - 最小化公共依赖:将公共依赖放在根 package.json
- 清晰的目录结构:如
packages/
放库,apps/
放应用 - CI 优化:只安装和构建受影响的工作区
- 文档规范:维护清晰的 monorepo 开发文档
常见问题解决
问题 1:如何解决工作区之间的循环依赖?
方案:重构代码消除循环依赖,或提取公共部分到新包
问题 2:某些包需要不同的 Node.js 版本?
- 方案:使用
.npmrc
配置use-node-version
或工具如nvm
/fnm
问题 3:如何限制某些包的访问?
- 方案:使用
pnpm.overrides
或resolutions
统一版本
PNPM 的工作区功能为 monorepo 提供了高效、可靠的解决方案,特别适合大型项目和多包管理的场景。
更新日志
2025/8/24 08:17
查看所有更新日志
e7112
-1于