packwise-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursorrules +23 -0
- package/CLAUDE.md +25 -0
- package/README.md +295 -0
- package/audit.md +224 -0
- package/bin/packwise.js +155 -0
- package/package.json +31 -0
- package/skill.md +719 -0
- package/sub-skills/ai/local-llm.md +183 -0
- package/sub-skills/ai/python-ml.md +164 -0
- package/sub-skills/backend/go-server.md +184 -0
- package/sub-skills/backend/java-spring.md +241 -0
- package/sub-skills/backend/node-server.md +164 -0
- package/sub-skills/backend/php-laravel.md +175 -0
- package/sub-skills/backend/python-server.md +164 -0
- package/sub-skills/backend/rust-backend.md +118 -0
- package/sub-skills/cli/python-cli.md +236 -0
- package/sub-skills/cli/sdk-library.md +497 -0
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -0
- package/sub-skills/cloud/docker.md +191 -0
- package/sub-skills/cloud/kubernetes.md +277 -0
- package/sub-skills/cloud/payment-integration.md +307 -0
- package/sub-skills/cross-platform/multiplatform.md +252 -0
- package/sub-skills/desktop/electron.md +783 -0
- package/sub-skills/desktop/game-dev.md +443 -0
- package/sub-skills/desktop/native-app.md +123 -0
- package/sub-skills/desktop/scenarios.md +443 -0
- package/sub-skills/desktop/smart-platforms.md +324 -0
- package/sub-skills/desktop/tauri.md +428 -0
- package/sub-skills/desktop/vr-ar.md +252 -0
- package/sub-skills/desktop/web-to-desktop.md +153 -0
- package/sub-skills/embedded/car-infotainment.md +129 -0
- package/sub-skills/embedded/esp32.md +184 -0
- package/sub-skills/embedded/ros.md +150 -0
- package/sub-skills/embedded/stm32.md +160 -0
- package/sub-skills/mobile/android.md +322 -0
- package/sub-skills/mobile/capacitor.md +232 -0
- package/sub-skills/mobile/flutter-mobile.md +138 -0
- package/sub-skills/mobile/harmonyos.md +150 -0
- package/sub-skills/mobile/ios.md +245 -0
- package/sub-skills/mobile/react-native.md +443 -0
- package/sub-skills/mobile/wearables.md +230 -0
- package/sub-skills/plugins/browser-extension.md +308 -0
- package/sub-skills/plugins/jetbrains-plugin.md +226 -0
- package/sub-skills/plugins/vscode-extension.md +204 -0
- package/sub-skills/security/security-tools.md +174 -0
- package/sub-skills/web/monorepo.md +274 -0
- package/sub-skills/web/pwa.md +220 -0
- package/sub-skills/web/serverless-edge.md +295 -0
- package/sub-skills/web/spa.md +266 -0
- package/sub-skills/web/ssr.md +228 -0
- package/sub-skills/web/wasm.md +243 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# VS Code Extension Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Develop and publish Visual Studio Code extensions.
|
|
4
|
+
|
|
5
|
+
**Current version**: VS Code 1.96+ / @vscode/vsce 2.x (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Editor enhancements (themes, snippets, keybindings)
|
|
10
|
+
- Language support (syntax highlighting, IntelliSense, debugging)
|
|
11
|
+
- Developer tools (linters, formatters, test runners)
|
|
12
|
+
- AI coding assistants
|
|
13
|
+
- Workflow automation
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Node.js 20+
|
|
19
|
+
# Install VS Code Extension Manager
|
|
20
|
+
npm install -g @vscode/vsce
|
|
21
|
+
|
|
22
|
+
# Install Yeoman generator for scaffolding
|
|
23
|
+
npm install -g yo generator-code
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Project Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Generate extension scaffold
|
|
30
|
+
yo code
|
|
31
|
+
# Select: New Extension (TypeScript)
|
|
32
|
+
# Name: my-extension
|
|
33
|
+
# Description: My awesome extension
|
|
34
|
+
# Package manager: npm
|
|
35
|
+
|
|
36
|
+
# Project structure:
|
|
37
|
+
my-extension/
|
|
38
|
+
├── src/
|
|
39
|
+
│ └── extension.ts ← Main entry point
|
|
40
|
+
├── package.json ← Extension manifest
|
|
41
|
+
├── tsconfig.json ← TypeScript config
|
|
42
|
+
├── .vscodeignore ← Files to exclude from .vsix
|
|
43
|
+
└── README.md
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## package.json (Extension Manifest)
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"name": "my-extension",
|
|
51
|
+
"displayName": "My Extension",
|
|
52
|
+
"description": "My awesome VS Code extension",
|
|
53
|
+
"version": "1.0.0",
|
|
54
|
+
"engines": { "vscode": "^1.96.0" },
|
|
55
|
+
"categories": ["Other"],
|
|
56
|
+
"activationEvents": [],
|
|
57
|
+
"main": "./out/extension.js",
|
|
58
|
+
"contributes": {
|
|
59
|
+
"commands": [
|
|
60
|
+
{
|
|
61
|
+
"command": "myExtension.helloWorld",
|
|
62
|
+
"title": "Hello World"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"keybindings": [
|
|
66
|
+
{
|
|
67
|
+
"command": "myExtension.helloWorld",
|
|
68
|
+
"key": "ctrl+shift+h",
|
|
69
|
+
"mac": "cmd+shift+h"
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"configuration": {
|
|
73
|
+
"title": "My Extension",
|
|
74
|
+
"properties": {
|
|
75
|
+
"myExtension.enableFeature": {
|
|
76
|
+
"type": "boolean",
|
|
77
|
+
"default": true,
|
|
78
|
+
"description": "Enable the awesome feature"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"compile": "tsc -p ./",
|
|
85
|
+
"watch": "tsc -watch -p ./",
|
|
86
|
+
"package": "vsce package",
|
|
87
|
+
"publish": "vsce publish"
|
|
88
|
+
},
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"@types/vscode": "^1.96.0",
|
|
91
|
+
"@types/node": "^22.0.0",
|
|
92
|
+
"typescript": "^5.7.0"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Build & Test
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Compile TypeScript
|
|
101
|
+
npm run compile
|
|
102
|
+
|
|
103
|
+
# Run in Extension Development Host (VS Code launches with your extension)
|
|
104
|
+
# Press F5 in VS Code, or:
|
|
105
|
+
code --extensionDevelopmentPath=.
|
|
106
|
+
|
|
107
|
+
# Run tests
|
|
108
|
+
npm test
|
|
109
|
+
|
|
110
|
+
# Lint
|
|
111
|
+
npm run lint
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Package (.vsix)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Package as .vsix file
|
|
118
|
+
vsce package
|
|
119
|
+
# Output: my-extension-1.0.0.vsix
|
|
120
|
+
|
|
121
|
+
# Install locally for testing
|
|
122
|
+
code --install-extension my-extension-1.0.0.vsix
|
|
123
|
+
|
|
124
|
+
# Package with specific version
|
|
125
|
+
vsce package --pre-release # Pre-release version
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Publish to Marketplace
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 1. Create Personal Access Token (PAT)
|
|
132
|
+
# dev.azure.com → User Settings → Personal Access Tokens
|
|
133
|
+
# Scope: Marketplace → Manage
|
|
134
|
+
|
|
135
|
+
# 2. Create publisher (one-time)
|
|
136
|
+
# marketplace.visualstudio.com → Create Publisher
|
|
137
|
+
|
|
138
|
+
# 3. Login
|
|
139
|
+
vsce login YOUR_PUBLISHER_NAME
|
|
140
|
+
# Enter PAT when prompted
|
|
141
|
+
|
|
142
|
+
# 4. Publish
|
|
143
|
+
vsce publish # Publish current version
|
|
144
|
+
vsce publish minor # Bump minor version + publish
|
|
145
|
+
vsce publish patch # Bump patch version + publish
|
|
146
|
+
vsce publish 2.0.0 # Set specific version + publish
|
|
147
|
+
|
|
148
|
+
# 5. Pre-release
|
|
149
|
+
vsce publish --pre-release
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Testing
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// src/test/suite/extension.test.ts
|
|
156
|
+
import * as assert from 'assert';
|
|
157
|
+
import * as vscode from 'vscode';
|
|
158
|
+
|
|
159
|
+
suite('Extension Test Suite', () => {
|
|
160
|
+
test('Command should be registered', async () => {
|
|
161
|
+
const commands = await vscode.commands.getCommands(true);
|
|
162
|
+
assert.ok(commands.includes('myExtension.helloWorld'));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('Configuration should have default value', () => {
|
|
166
|
+
const config = vscode.workspace.getConfiguration('myExtension');
|
|
167
|
+
assert.strictEqual(config.get('enableFeature'), true);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Run tests
|
|
174
|
+
npm test
|
|
175
|
+
# Or with coverage
|
|
176
|
+
npm run test:coverage
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Extension Types
|
|
180
|
+
|
|
181
|
+
| Type | Use Case | Key APIs |
|
|
182
|
+
|------|----------|---------|
|
|
183
|
+
| Commands | Custom actions | `vscode.commands.registerCommand` |
|
|
184
|
+
| Webview | Custom UI panels | `vscode.window.createWebviewPanel` |
|
|
185
|
+
| Language Server | Language support | `vscode-languageclient` / `vscode-languageserver` |
|
|
186
|
+
| Tree View | Custom sidebars | `TreeDataProvider` |
|
|
187
|
+
| Debug Adapter | Custom debuggers | `DebugAdapterDescriptorFactory` |
|
|
188
|
+
| Notebook | Jupyter-like notebooks | `NotebookSerializer` |
|
|
189
|
+
| Chat Participant | AI chat integration | `vscode.chat.createChatParticipant` |
|
|
190
|
+
|
|
191
|
+
## Common Pitfalls
|
|
192
|
+
|
|
193
|
+
| Issue | Fix |
|
|
194
|
+
|-------|-----|
|
|
195
|
+
| Build failure | Confirm `tsconfig.json` `outDir` matches `main` field in package.json |
|
|
196
|
+
| Publish rejected | Ensure all required fields: `name`, `displayName`, `description`, `version`, `engines` |
|
|
197
|
+
| Size limit | .vsix max 100MB; use `.vscodeignore` to exclude node_modules source |
|
|
198
|
+
| Icon requirement | At least 128x128 PNG; set in `package.json` → `icon` |
|
|
199
|
+
| Extension not activating | Check `activationEvents`; use `"*"` for testing (slow), be specific in production |
|
|
200
|
+
| Webview not showing | Check CSP headers; set `enableScripts: true` |
|
|
201
|
+
| Tests failing in CI | Use `@vscode/test-electron` for integration tests |
|
|
202
|
+
| API version mismatch | Check `engines.vscode` in package.json matches your target version |
|
|
203
|
+
| `@types/vscode` version | Should match `engines.vscode` version |
|
|
204
|
+
| Extension size too large | Use esbuild/webpack bundler; exclude devDependencies |
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Security Tools Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build and package security tools: penetration testing tools, vulnerability scanners, security monitoring, and CLI utilities.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- Penetration testing / offensive security tools
|
|
8
|
+
- Vulnerability scanners (SAST/DAST)
|
|
9
|
+
- Security monitoring platforms (SIEM)
|
|
10
|
+
- Encryption / cryptographic tools
|
|
11
|
+
- Compliance checking tools
|
|
12
|
+
- CTF (Capture The Flag) tools
|
|
13
|
+
|
|
14
|
+
## Tech Stack Overview
|
|
15
|
+
|
|
16
|
+
| Language | Strengths | Package Method | Best For |
|
|
17
|
+
|----------|-----------|---------------|----------|
|
|
18
|
+
| Python | Rapid prototyping, rich security libraries | PyInstaller / Docker / pipx | Script tools, scanners, automation |
|
|
19
|
+
| Go | Static binary, cross-compile, high concurrency | `go build` | Network tools, high-perf scanners |
|
|
20
|
+
| Rust | Memory safety, performance | `cargo build --release` | Low-level tools, cryptographic operations |
|
|
21
|
+
| C | Maximum control, minimal dependencies | Native compilation | Kernel modules, exploit development |
|
|
22
|
+
|
|
23
|
+
## Python Security Tools
|
|
24
|
+
|
|
25
|
+
### PyInstaller (Standalone Binary)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Install
|
|
29
|
+
pip install pyinstaller
|
|
30
|
+
|
|
31
|
+
# Single-file executable
|
|
32
|
+
pyinstaller --onefile --name scanner scanner.py
|
|
33
|
+
|
|
34
|
+
# With hidden imports (common for security libs)
|
|
35
|
+
pyinstaller --onefile \
|
|
36
|
+
--hidden-import=cryptography \
|
|
37
|
+
--hidden-import=paramiko \
|
|
38
|
+
--hidden-import=scapy \
|
|
39
|
+
--name scanner scanner.py
|
|
40
|
+
|
|
41
|
+
# Console app (no GUI)
|
|
42
|
+
pyinstaller --onefile --console --name vuln-scanner scanner.py
|
|
43
|
+
|
|
44
|
+
# Output: dist/scanner (Linux/macOS) or dist/scanner.exe (Windows)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### pipx (Isolated CLI Installation)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Install pipx
|
|
51
|
+
pip install pipx
|
|
52
|
+
pipx ensurepath
|
|
53
|
+
|
|
54
|
+
# Install security tool in isolated environment
|
|
55
|
+
pipx install bandit # Python SAST linter
|
|
56
|
+
pipx install safety # Dependency vulnerability scanner
|
|
57
|
+
pipx install semgrep # Multi-language SAST
|
|
58
|
+
pipx install trivy # Container/filesystem scanner
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Docker (Reproducible Environment)
|
|
62
|
+
|
|
63
|
+
```dockerfile
|
|
64
|
+
FROM python:3.13-slim
|
|
65
|
+
|
|
66
|
+
# Install system dependencies (common for security tools)
|
|
67
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
68
|
+
nmap \
|
|
69
|
+
masscan \
|
|
70
|
+
net-tools \
|
|
71
|
+
iputils-ping \
|
|
72
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
73
|
+
|
|
74
|
+
WORKDIR /app
|
|
75
|
+
COPY requirements.txt .
|
|
76
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
77
|
+
|
|
78
|
+
COPY . .
|
|
79
|
+
|
|
80
|
+
# Run as non-root (important for security tools too)
|
|
81
|
+
RUN useradd -m scanner
|
|
82
|
+
USER scanner
|
|
83
|
+
|
|
84
|
+
ENTRYPOINT ["python", "scanner.py"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Go Security Tools
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Single binary, no dependencies
|
|
91
|
+
CGO_ENABLED=0 go build -ldflags="-s -w" -o scanner .
|
|
92
|
+
|
|
93
|
+
# Cross-compile
|
|
94
|
+
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o scanner-linux .
|
|
95
|
+
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o scanner.exe .
|
|
96
|
+
GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -o scanner-mac .
|
|
97
|
+
|
|
98
|
+
# With version embedding
|
|
99
|
+
go build -ldflags="-s -w -X main.version=$(git describe --tags)" -o scanner .
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Rust Security Tools
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Release build (optimized)
|
|
106
|
+
cargo build --release
|
|
107
|
+
# Output: target/release/scanner
|
|
108
|
+
|
|
109
|
+
# Cross-compile with cross
|
|
110
|
+
cargo install cross
|
|
111
|
+
cross build --release --target x86_64-unknown-linux-musl
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## C Security Tools
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Static binary (portable)
|
|
118
|
+
gcc -static -O2 -o scanner scanner.c
|
|
119
|
+
|
|
120
|
+
# With hardening flags
|
|
121
|
+
gcc -O2 -fstack-protector-all -D_FORTIFY_SOURCE=2 \
|
|
122
|
+
-Wformat -Wformat-security -o scanner scanner.c
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Signing & Distribution
|
|
126
|
+
|
|
127
|
+
### Signing Binaries (Trust)
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Windows: Sign with code signing certificate
|
|
131
|
+
signtool sign /f cert.pfx /p password /tr http://timestamp.digicert.com scanner.exe
|
|
132
|
+
|
|
133
|
+
# macOS: Sign and notarize
|
|
134
|
+
codesign --force --sign "Developer ID Application: Your Name" scanner
|
|
135
|
+
xcrun notarytool submit scanner.zip --apple-id your@email.com --password app-specific-pw
|
|
136
|
+
|
|
137
|
+
# Linux: GPG sign
|
|
138
|
+
gpg --detach-sign --armor scanner
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Distribution Channels
|
|
142
|
+
|
|
143
|
+
| Channel | Method | Best For |
|
|
144
|
+
|---------|--------|---------|
|
|
145
|
+
| GitHub Releases | `gh release create v1.0 scanner-linux scanner.exe` | Open source tools |
|
|
146
|
+
| PyPI / TestPyPI | `twine upload dist/*` | Python libraries/tools |
|
|
147
|
+
| Docker Hub | `docker build -t org/scanner . && docker push org/scanner` | Containerized tools |
|
|
148
|
+
| Homebrew | Create tap formula | macOS CLI tools |
|
|
149
|
+
| AUR | Submit PKGBUILD | Arch Linux users |
|
|
150
|
+
| Cargo crates.io | `cargo publish` | Rust libraries/tools |
|
|
151
|
+
|
|
152
|
+
## Compliance & Ethics
|
|
153
|
+
|
|
154
|
+
| Requirement | Implementation |
|
|
155
|
+
|-------------|---------------|
|
|
156
|
+
| Legal authorization | Add usage disclaimer; require explicit authorization flag |
|
|
157
|
+
| Logging | Log all operations with timestamps to file |
|
|
158
|
+
| Data protection | Encrypt scan results; don't hardcode credentials |
|
|
159
|
+
| Distribution control | Consider private distribution for offensive tools |
|
|
160
|
+
| Rate limiting | Implement request throttling to avoid DoS |
|
|
161
|
+
| Disclosure | Follow responsible disclosure for found vulnerabilities |
|
|
162
|
+
|
|
163
|
+
## Common Pitfalls
|
|
164
|
+
|
|
165
|
+
| Issue | Fix |
|
|
166
|
+
|-------|-----|
|
|
167
|
+
| PyInstaller missing modules | Use `--hidden-import` for dynamically loaded security libraries |
|
|
168
|
+
| Static binary too large | Use `upx --best` to compress (Go/Rust binaries) |
|
|
169
|
+
| Permission denied (network tools) | Use Linux capabilities: `setcap cap_net_raw+ep scanner` |
|
|
170
|
+
| Import errors in packaged binary | Test in a clean VM/container; PyInstaller may miss C extensions |
|
|
171
|
+
| Anti-virus false positive | Sign binaries; submit to AV vendors for whitelisting |
|
|
172
|
+
| Cross-compile fails (CGO) | Use Docker or `cross` tool; set `CGO_ENABLED=0` when possible |
|
|
173
|
+
| System tool dependency | Package with Docker; document required system tools |
|
|
174
|
+
| Hardcoded credentials in source | Use environment variables; add to `.gitignore` |
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Monorepo Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Manage and build multi-package projects using monorepo tools.
|
|
4
|
+
|
|
5
|
+
**Current version**: Turborepo 2.x / pnpm 9.x / Nx 20.x (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Multiple related packages/apps in one repository
|
|
10
|
+
- Shared code (UI components, utilities, types) across projects
|
|
11
|
+
- Need coordinated builds with dependency-aware caching
|
|
12
|
+
- Want atomic commits across packages
|
|
13
|
+
|
|
14
|
+
## Tool Comparison
|
|
15
|
+
|
|
16
|
+
| Feature | Turborepo 2.x | Nx 20.x | pnpm Workspaces |
|
|
17
|
+
|---------|--------------|---------|-----------------|
|
|
18
|
+
| Approach | Build orchestrator | Full dev platform | Package manager feature |
|
|
19
|
+
| Caching | Local + Remote | Local + Remote (Nx Cloud) | Not built-in |
|
|
20
|
+
| Language support | Any | JS/TS, Go, Java, .NET | JS/TS only |
|
|
21
|
+
| Learning curve | Low | Medium | Lowest |
|
|
22
|
+
| Task runner | Built-in (turbo.json) | Built-in (project.json) | Use with Turborepo/Nx |
|
|
23
|
+
| Affected detection | Yes | Yes (more granular) | No |
|
|
24
|
+
| Plugin ecosystem | Smaller | Large (generators, executors) | N/A |
|
|
25
|
+
| Best for | JS/TS monorepos, simplicity | Large teams, polyglot monorepos | Package management only |
|
|
26
|
+
|
|
27
|
+
## pnpm Workspaces (Foundation)
|
|
28
|
+
|
|
29
|
+
Most JS/TS monorepos use pnpm as the package manager regardless of build tool.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Install pnpm
|
|
33
|
+
npm install -g pnpm@latest
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
# pnpm-workspace.yaml (project root)
|
|
38
|
+
packages:
|
|
39
|
+
- "apps/*"
|
|
40
|
+
- "packages/*"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
my-monorepo/
|
|
45
|
+
├── apps/
|
|
46
|
+
│ ├── web/ # Frontend app
|
|
47
|
+
│ ├── admin/ # Admin dashboard
|
|
48
|
+
│ └── api/ # Backend API
|
|
49
|
+
├── packages/
|
|
50
|
+
│ ├── ui/ # Shared UI components
|
|
51
|
+
│ ├── utils/ # Shared utilities
|
|
52
|
+
│ ├── tsconfig/ # Shared TypeScript configs
|
|
53
|
+
│ └── eslint-config/ # Shared ESLint configs
|
|
54
|
+
├── pnpm-workspace.yaml
|
|
55
|
+
├── pnpm-lock.yaml
|
|
56
|
+
└── package.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
// Root package.json
|
|
61
|
+
{
|
|
62
|
+
"name": "my-monorepo",
|
|
63
|
+
"private": true,
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "turbo run build",
|
|
66
|
+
"dev": "turbo run dev",
|
|
67
|
+
"lint": "turbo run lint",
|
|
68
|
+
"test": "turbo run test"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"turbo": "^2.3.0"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
// apps/web/package.json — use workspace: protocol for internal deps
|
|
78
|
+
{
|
|
79
|
+
"name": "@myrepo/web",
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@myrepo/ui": "workspace:*",
|
|
82
|
+
"@myrepo/utils": "workspace:*"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Turborepo
|
|
88
|
+
|
|
89
|
+
### Configuration
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
// turbo.json
|
|
93
|
+
{
|
|
94
|
+
"$schema": "https://turbo.build/schema.json",
|
|
95
|
+
"tasks": {
|
|
96
|
+
"build": {
|
|
97
|
+
"dependsOn": ["^build"],
|
|
98
|
+
"outputs": ["dist/**", ".next/**", "build/**"],
|
|
99
|
+
"cache": true
|
|
100
|
+
},
|
|
101
|
+
"dev": {
|
|
102
|
+
"cache": false,
|
|
103
|
+
"persistent": true
|
|
104
|
+
},
|
|
105
|
+
"lint": {
|
|
106
|
+
"dependsOn": ["^build"]
|
|
107
|
+
},
|
|
108
|
+
"test": {
|
|
109
|
+
"dependsOn": ["build"],
|
|
110
|
+
"outputs": ["coverage/**"]
|
|
111
|
+
},
|
|
112
|
+
"clean": {
|
|
113
|
+
"cache": false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Build Commands
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Build all packages in dependency order
|
|
123
|
+
turbo run build
|
|
124
|
+
|
|
125
|
+
# Build only packages affected by changes
|
|
126
|
+
turbo run build --filter=...[HEAD^1]
|
|
127
|
+
|
|
128
|
+
# Build specific package and its dependencies
|
|
129
|
+
turbo run build --filter=@myrepo/web...
|
|
130
|
+
|
|
131
|
+
# Build with remote caching (Vercel)
|
|
132
|
+
turbo run build --team=myteam --token=$TURBO_TOKEN
|
|
133
|
+
|
|
134
|
+
# Dry run (show execution plan without building)
|
|
135
|
+
turbo run build --dry-run
|
|
136
|
+
|
|
137
|
+
# Run multiple tasks
|
|
138
|
+
turbo run build lint test
|
|
139
|
+
|
|
140
|
+
# Clear cache
|
|
141
|
+
turbo run clean
|
|
142
|
+
turbo prune # Remove unused cache entries
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Remote Caching
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Link to Vercel remote cache
|
|
149
|
+
npx turbo login
|
|
150
|
+
npx turbo link
|
|
151
|
+
|
|
152
|
+
# Or self-hosted: set TURBO_API and TURBO_TOKEN
|
|
153
|
+
export TURBO_API=https://my-cache-server.com
|
|
154
|
+
export TURBO_TOKEN=my-token
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Nx
|
|
158
|
+
|
|
159
|
+
### Setup
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Add Nx to existing monorepo
|
|
163
|
+
npx nx init
|
|
164
|
+
|
|
165
|
+
# Or create new Nx workspace
|
|
166
|
+
npx create-nx-workspace my-monorepo --preset=ts
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Configuration
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
// nx.json
|
|
173
|
+
{
|
|
174
|
+
"tasksRunnerOptions": {
|
|
175
|
+
"default": {
|
|
176
|
+
"runner": "nx/tasks-runners/default",
|
|
177
|
+
"options": {
|
|
178
|
+
"cacheableOperations": ["build", "test", "lint"]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"targetDefaults": {
|
|
183
|
+
"build": {
|
|
184
|
+
"dependsOn": ["^build"],
|
|
185
|
+
"outputs": ["{projectRoot}/dist"]
|
|
186
|
+
},
|
|
187
|
+
"test": {
|
|
188
|
+
"dependsOn": ["build"]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
// apps/web/project.json
|
|
196
|
+
{
|
|
197
|
+
"name": "web",
|
|
198
|
+
"sourceRoot": "apps/web/src",
|
|
199
|
+
"targets": {
|
|
200
|
+
"build": {
|
|
201
|
+
"executor": "@nx/vite:build",
|
|
202
|
+
"outputs": ["{options.outputPath}"],
|
|
203
|
+
"options": {
|
|
204
|
+
"outputPath": "dist/apps/web"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"dev": {
|
|
208
|
+
"executor": "@nx/vite:dev-server"
|
|
209
|
+
},
|
|
210
|
+
"test": {
|
|
211
|
+
"executor": "@nx/vite:test"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Build Commands
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Build all
|
|
221
|
+
npx nx run-many -t build
|
|
222
|
+
|
|
223
|
+
# Build affected only (compares with main branch)
|
|
224
|
+
npx nx affected -t build
|
|
225
|
+
|
|
226
|
+
# Build specific project
|
|
227
|
+
npx nx build web
|
|
228
|
+
|
|
229
|
+
# Graph visualization
|
|
230
|
+
npx nx graph
|
|
231
|
+
|
|
232
|
+
# Remote cache (Nx Cloud)
|
|
233
|
+
npx nx connect-to-nx-cloud
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## CI/CD — GitHub Actions (Turborepo)
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
name: Monorepo Build
|
|
240
|
+
on:
|
|
241
|
+
push:
|
|
242
|
+
branches: [main]
|
|
243
|
+
pull_request:
|
|
244
|
+
|
|
245
|
+
jobs:
|
|
246
|
+
build:
|
|
247
|
+
runs-on: ubuntu-latest
|
|
248
|
+
steps:
|
|
249
|
+
- uses: actions/checkout@v4
|
|
250
|
+
with:
|
|
251
|
+
fetch-depth: 2 # Needed for affected detection
|
|
252
|
+
- uses: actions/setup-node@v4
|
|
253
|
+
with:
|
|
254
|
+
node-version: '22'
|
|
255
|
+
- run: npm install -g pnpm
|
|
256
|
+
- run: pnpm install --frozen-lockfile
|
|
257
|
+
- run: pnpm turbo run build lint test
|
|
258
|
+
env:
|
|
259
|
+
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
260
|
+
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Common Pitfalls
|
|
264
|
+
|
|
265
|
+
| Issue | Fix |
|
|
266
|
+
|-------|-----|
|
|
267
|
+
| `workspace:*` dependency not resolved | Ensure `pnpm-workspace.yaml` includes the package's directory |
|
|
268
|
+
| Circular dependency between packages | Restructure; extract shared code to a third package |
|
|
269
|
+
| Cache hit but stale output | `turbo run build --force` to bypass cache |
|
|
270
|
+
| `turbo` not found | Add to root `devDependencies` or install globally |
|
|
271
|
+
| Nx graph shows wrong dependencies | Check `import` paths; ensure `tsconfig.json` paths are correct |
|
|
272
|
+
| Phantom dependencies | pnpm prevents this by default; don't use `shamefully-hoist` |
|
|
273
|
+
| Type errors across packages | Use `workspace:*` + TypeScript project references |
|
|
274
|
+
| `pnpm install` fails with lockfile conflicts | Use `--frozen-lockfile` in CI; regenerate with `pnpm install --lockfile-only` |
|