--- name: pnpm-workspaces description: 通过工作空间实现 monorepo 支持,用于管理多个包 --- # pnpm Workspaces pnpm 通过工作空间(workspaces)内置支持 monorepo(多包仓库)。 ## 设置工作空间 在仓库根目录创建 `pnpm-workspace.yaml`: ```yaml packages: # 包含 packages/ 目录下的所有包 - 'packages/*' # 包含所有应用 - 'apps/*' # 包含嵌套的包 - 'tools/*/packages/*' # 排除测试目录 - '!**/test/**' ``` ## 工作空间协议 使用 `workspace:` 协议引用本地包: ```json { "dependencies": { "@myorg/utils": "workspace:*", "@myorg/core": "workspace:^", "@myorg/types": "workspace:~" } } ``` ### 协议变体 | 协议 | 行为 | 发布时转换 | |----------|----------|--------------| | `workspace:*` | 任意版本 | 实际版本(如 `1.2.3`) | | `workspace:^` | 兼容版本 | `^1.2.3` | | `workspace:~` | 补丁版本 | `~1.2.3` | | `workspace:^1.0.0` | Semver 范围 | `^1.0.0` | ## 过滤包 使用 `--filter` 在特定包上运行命令: ```bash # 按包名 pnpm --filter @myorg/app build pnpm -F @myorg/app build # 按目录路径 pnpm --filter "./packages/core" test # Glob 模式 pnpm --filter "@myorg/*" lint pnpm --filter "!@myorg/internal-*" publish # 所有包 pnpm -r build pnpm --recursive build ``` ### 基于依赖关系的过滤 ```bash # 包及其所有依赖 pnpm --filter "...@myorg/app" build # 包及其所有依赖者 pnpm --filter "@myorg/core..." test # 双向 pnpm --filter "...@myorg/shared..." build # 自 git 引用以来的变更 pnpm --filter "...[origin/main]" test pnpm --filter "[HEAD~5]" lint ``` ## 工作空间命令 ### 安装依赖 ```bash # 安装所有工作空间包 pnpm install # 向特定包添加依赖 pnpm --filter @myorg/app add lodash # 添加工作空间依赖 pnpm --filter @myorg/app add @myorg/utils ``` ### 运行脚本 ```bash # 在所有包含该脚本的包中运行 pnpm -r run build # 按拓扑顺序运行(依赖优先) pnpm -r --workspace-concurrency=1 run build # 并行运行 pnpm -r --parallel run test # 流式输出 pnpm -r --stream run dev ``` ### 执行命令 ```bash # 在所有包中运行命令 pnpm -r exec pwd # 在特定包中运行 pnpm --filter "./packages/**" exec rm -rf dist ``` ## 工作空间设置 在 `.npmrc` 或 `pnpm-workspace.yaml` 中配置: ```ini # 自动链接工作空间包 link-workspace-packages=true # 优先使用工作空间包而非注册表 prefer-workspace-packages=true # 单一锁文件(推荐) shared-workspace-lockfile=true # 工作空间协议处理方式 save-workspace-protocol=rolling # 并发工作空间脚本数 workspace-concurrency=4 ``` ## 发布工作空间 发布时,`workspace:` 协议会被转换: ```json // 发布前 { "dependencies": { "@myorg/utils": "workspace:^" } } // 发布后 { "dependencies": { "@myorg/utils": "^1.2.3" } } ``` 从 CI 发布时使用 `--no-git-checks`: ```bash pnpm publish -r --no-git-checks ``` ## 最佳实践 1. **对内部依赖使用 workspace 协议** 2. **启用 `link-workspace-packages`** 以实现自动链接 3. **使用共享锁文件** 以保证一致性 4. **构建时按依赖过滤** 以确保正确的顺序 5. **使用目录(catalogs)** 管理共享的外部依赖版本 ## 项目结构示例 ``` my-monorepo/ ├── pnpm-workspace.yaml ├── package.json ├── pnpm-lock.yaml ├── packages/ │ ├── core/ │ │ └── package.json │ ├── utils/ │ │ └── package.json │ └── types/ │ └── package.json └── apps/ ├── web/ │ └── package.json └── api/ └── package.json ```