Initial commit

This commit is contained in:
2026-04-17 23:26:01 +00:00
commit 2ea4ca5d52
409 changed files with 63459 additions and 0 deletions

View File

@@ -0,0 +1,205 @@
---
name: pnpm-workspaces
description: Monorepo support with workspaces for managing multiple packages
---
# pnpm Workspaces
pnpm has built-in support for monorepos (multi-package repositories) through workspaces.
## Setting Up Workspaces
Create `pnpm-workspace.yaml` at the repository root:
```yaml
packages:
# Include all packages in packages/ directory
- 'packages/*'
# Include all apps
- 'apps/*'
# Include nested packages
- 'tools/*/packages/*'
# Exclude test directories
- '!**/test/**'
```
## Workspace Protocol
Use `workspace:` protocol to reference local packages:
```json
{
"dependencies": {
"@myorg/utils": "workspace:*",
"@myorg/core": "workspace:^",
"@myorg/types": "workspace:~"
}
}
```
### Protocol Variants
| Protocol | Behavior | Published As |
|----------|----------|--------------|
| `workspace:*` | Any version | Actual version (e.g., `1.2.3`) |
| `workspace:^` | Compatible version | `^1.2.3` |
| `workspace:~` | Patch version | `~1.2.3` |
| `workspace:^1.0.0` | Semver range | `^1.0.0` |
## Filtering Packages
Run commands on specific packages using `--filter`:
```bash
# By package name
pnpm --filter @myorg/app build
pnpm -F @myorg/app build
# By directory path
pnpm --filter "./packages/core" test
# Glob patterns
pnpm --filter "@myorg/*" lint
pnpm --filter "!@myorg/internal-*" publish
# All packages
pnpm -r build
pnpm --recursive build
```
### Dependency-based Filtering
```bash
# Package and all its dependencies
pnpm --filter "...@myorg/app" build
# Package and all its dependents
pnpm --filter "@myorg/core..." test
# Both directions
pnpm --filter "...@myorg/shared..." build
# Changed since git ref
pnpm --filter "...[origin/main]" test
pnpm --filter "[HEAD~5]" lint
```
## Workspace Commands
### Install dependencies
```bash
# Install all workspace packages
pnpm install
# Add dependency to specific package
pnpm --filter @myorg/app add lodash
# Add workspace dependency
pnpm --filter @myorg/app add @myorg/utils
```
### Run scripts
```bash
# Run in all packages with that script
pnpm -r run build
# Run in topological order (dependencies first)
pnpm -r --workspace-concurrency=1 run build
# Run in parallel
pnpm -r --parallel run test
# Stream output
pnpm -r --stream run dev
```
### Execute commands
```bash
# Run command in all packages
pnpm -r exec pwd
# Run in specific packages
pnpm --filter "./packages/**" exec rm -rf dist
```
## Workspace Settings
Configure in `.npmrc` or `pnpm-workspace.yaml`:
```ini
# Link workspace packages automatically
link-workspace-packages=true
# Prefer workspace packages over registry
prefer-workspace-packages=true
# Single lockfile (recommended)
shared-workspace-lockfile=true
# Workspace protocol handling
save-workspace-protocol=rolling
# Concurrent workspace scripts
workspace-concurrency=4
```
## Publishing Workspaces
When publishing, `workspace:` protocols are converted:
```json
// Before publish
{
"dependencies": {
"@myorg/utils": "workspace:^"
}
}
// After publish
{
"dependencies": {
"@myorg/utils": "^1.2.3"
}
}
```
Use `--no-git-checks` for publishing from CI:
```bash
pnpm publish -r --no-git-checks
```
## Best Practices
1. **Use workspace protocol** for internal dependencies
2. **Enable `link-workspace-packages`** for automatic linking
3. **Use shared lockfile** for consistency
4. **Filter by dependencies** when building to ensure correct order
5. **Use catalogs** for shared external dependency versions
## Example Project Structure
```
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
```
<!--
Source references:
- https://pnpm.io/workspaces
- https://pnpm.io/filtering
- https://pnpm.io/npmrc#workspace-settings
-->