pnpm-workspace

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

pnpm Workspace

pnpm Workspace

Overview

概述

pnpm workspaces provide built-in monorepo support through
pnpm-workspace.yaml
, the
workspace:
protocol for local package linking, and powerful filtering to run commands across specific packages. Catalogs enforce consistent dependency versions across all workspace packages.
When to use: Multi-package repositories, shared libraries with consuming apps, consistent dependency management across packages, running commands on subsets of packages.
When NOT to use: Single-package projects, projects already using npm/yarn workspaces (migration required), projects that need floating dependency versions per package.
pnpm workspaces通过
pnpm-workspace.yaml
、用于本地包链接的
workspace:
协议,以及强大的过滤功能为monorepo提供内置支持,可跨特定包运行命令。Catalogs可确保所有工作区包的依赖版本保持一致。
适用场景: 多包仓库、包含消费应用的共享库、跨包的一致依赖管理、在部分包子集上运行命令。
不适用场景: 单包项目、已使用npm/yarn workspaces的项目(需要迁移)、每个包需要浮动依赖版本的项目。

Quick Reference

快速参考

PatternAPI / ConfigKey Points
Define workspace
pnpm-workspace.yaml
with
packages
globs
Globs match directories containing
package.json
Link local package
"dep": "workspace:*"
Always resolves to local workspace package
Link with version range
"dep": "workspace:^1.0.0"
Fails install if local version does not satisfy range
Default catalog
catalog:
key in
pnpm-workspace.yaml
Single source of truth for dependency versions
Named catalog
catalogs:
key with named groups
Multiple version sets (e.g.,
react18
,
react17
)
Use catalog in package
"dep": "catalog:"
or
"dep": "catalog:name"
Resolved to actual version on
pnpm publish
Filter by name
--filter <name>
or
-F <name>
Exact name or glob pattern (
@scope/*
)
Filter with dependencies
--filter "foo..."
Package and all its dependencies
Filter with dependents
--filter "...foo"
Package and all packages that depend on it
Filter by directory
--filter "./packages/app"
All packages under a directory path
Filter by git changes
--filter "[origin/main]"
Packages changed since a commit or branch
Exclude from filter
--filter "!foo"
Remove matching packages from selection
Run script in package
pnpm --filter <pkg> <script>
Runs script only in matched packages
Recursive run
pnpm -r run <script>
Runs script in all workspace packages
Install all
pnpm install
Single lockfile for entire workspace
Publish workspace pkg
pnpm publish
Replaces
workspace:
and
catalog:
with real versions
Inject workspace deps
inject-workspace-packages=true
in
.npmrc
Hard-links instead of symlinks; required for deploy
Script security (v10+)
allowBuilds
in
package.json
Lifecycle scripts blocked by default; opt-in per dep
模式API/配置关键点
定义工作区带有
packages
通配符的
pnpm-workspace.yaml
通配符匹配包含
package.json
的目录
链接本地包
"dep": "workspace:*"
始终解析为本地工作区包
带版本范围的链接
"dep": "workspace:^1.0.0"
若本地版本不满足范围,安装会失败
默认Catalog
pnpm-workspace.yaml
中的
catalog:
依赖版本的单一可信来源
命名Catalog带有命名分组的
catalogs:
多版本集合(例如
react18
react17
在包中使用Catalog
"dep": "catalog:"
"dep": "catalog:name"
pnpm publish
时会解析为实际版本
按名称过滤
--filter <name>
-F <name>
精确名称或通配符模式(
@scope/*
按依赖过滤
--filter "foo..."
包及其所有依赖
按被依赖过滤
--filter "...foo"
包及其所有依赖它的包
按目录过滤
--filter "./packages/app"
指定目录下的所有包
按Git变更过滤
--filter "[origin/main]"
自某次提交或分支以来有变更的包
从过滤结果中排除
--filter "!foo"
从选中的包中移除匹配的包
在包中运行脚本
pnpm --filter <pkg> <script>
仅在匹配的包中运行脚本
递归运行
pnpm -r run <script>
在所有工作区包中运行脚本
安装所有依赖
pnpm install
整个工作区使用单一锁文件
发布工作区包
pnpm publish
workspace:
catalog:
替换为实际版本
注入工作区依赖
.npmrc
中设置
inject-workspace-packages=true
使用硬链接而非符号链接;部署时必需
脚本安全性(v10+)
package.json
中的
allowBuilds
默认阻止生命周期脚本;需为每个依赖手动开启

Common Mistakes

常见错误

MistakeCorrect Pattern
Using
workspace:*
then publishing as-is
pnpm automatically replaces
workspace:*
with real versions on publish
Forgetting to list directory in
packages:
Every package directory must match a glob in
pnpm-workspace.yaml
Using
npm install
in workspace packages
Always use
pnpm install
from the workspace root
Hardcoding versions duplicated across packagesUse
catalog:
to centralize version definitions
Running
pnpm install
inside a sub-package
Run from workspace root; use
--filter
to target packages
Expecting
--filter
to match directory names
--filter
matches
package.json
name
field, not directory names
Not escaping
!
in zsh for exclude filters
Use
\!
or quote the filter:
--filter="!foo"
Using
workspace:
for non-workspace deps
workspace:
protocol only works for packages defined in the workspace
Lifecycle scripts failing after pnpm 10 upgradepnpm 10 blocks scripts by default; add deps to
allowBuilds
in config
Using
pnpm deploy
without
inject-workspace-packages
Set
inject-workspace-packages=true
in
.npmrc
(required in pnpm 10)
错误操作正确做法
使用
workspace:*
后直接发布
pnpm会在发布时自动将
workspace:*
替换为实际版本
忘记在
packages:
中列出目录
每个包目录必须匹配
pnpm-workspace.yaml
中的某个通配符
在工作区包中使用
npm install
始终从工作区根目录运行
pnpm install
在多个包中硬编码重复的版本使用
catalog:
集中管理版本定义
在子包内运行
pnpm install
从工作区根目录运行;使用
--filter
指定目标包
期望
--filter
匹配目录名称
--filter
匹配的是
package.json
中的
name
字段,而非目录名称
在zsh中使用排除过滤时未转义
!
使用
\!
或给过滤条件加引号:
--filter="!foo"
对非工作区依赖使用
workspace:
workspace:
协议仅适用于工作区中定义的包
升级到pnpm 10后生命周期脚本执行失败pnpm 10默认阻止脚本;需在配置中将依赖添加到
allowBuilds
未设置
inject-workspace-packages
就使用
pnpm deploy
.npmrc
中设置
inject-workspace-packages=true
(pnpm 10中必需)

Delegation

任务委托

  • Workspace scaffolding: Use
    Explore
    agent to discover existing package structure
  • Dependency auditing: Use
    Task
    agent to check version consistency across packages
If the
turborepo
skill is available, delegate build orchestration, task caching, and CI optimization to it. If the
changesets
skill is available, delegate versioning, changelog generation, and npm publishing to it.
  • 工作区脚手架搭建:使用Explore Agent探索现有包结构
  • 依赖审计:使用Task Agent检查跨包的版本一致性
turborepo
Skill可用,将构建编排、任务缓存和CI优化委托给它。 若
changesets
Skill可用,将版本管理、变更日志生成和npm发布委托给它。

References

参考资料

  • Workspace setup, workspace protocol, and catalogs
  • Filtering packages for targeted commands
  • Shared configuration across workspace packages
  • Monorepo integration: pnpm + Turborepo + Changesets pipeline
  • 工作区设置、workspace协议和Catalogs
  • 针对目标命令过滤包
  • 跨工作区包共享配置
  • Monorepo集成:pnpm + Turborepo + Changesets流水线