omgkit 2.0.7 → 2.1.1
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/package.json +2 -2
- package/plugin/skills/backend/api-architecture/SKILL.md +857 -0
- package/plugin/skills/backend/caching-strategies/SKILL.md +755 -0
- package/plugin/skills/backend/event-driven-architecture/SKILL.md +753 -0
- package/plugin/skills/backend/real-time-systems/SKILL.md +635 -0
- package/plugin/skills/databases/database-optimization/SKILL.md +571 -0
- package/plugin/skills/databases/postgresql/SKILL.md +494 -18
- package/plugin/skills/devops/docker/SKILL.md +466 -18
- package/plugin/skills/devops/monorepo-management/SKILL.md +595 -0
- package/plugin/skills/devops/observability/SKILL.md +622 -0
- package/plugin/skills/devops/performance-profiling/SKILL.md +905 -0
- package/plugin/skills/frameworks/nextjs/SKILL.md +407 -44
- package/plugin/skills/frameworks/react/SKILL.md +1006 -32
- package/plugin/skills/frontend/advanced-ui-design/SKILL.md +426 -0
- package/plugin/skills/integrations/ai-integration/SKILL.md +730 -0
- package/plugin/skills/integrations/payment-integration/SKILL.md +735 -0
- package/plugin/skills/languages/python/SKILL.md +489 -25
- package/plugin/skills/languages/typescript/SKILL.md +379 -30
- package/plugin/skills/methodology/problem-solving/SKILL.md +355 -0
- package/plugin/skills/methodology/research-validation/SKILL.md +668 -0
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +260 -0
- package/plugin/skills/mobile/mobile-development/SKILL.md +756 -0
- package/plugin/skills/security/security-hardening/SKILL.md +633 -0
- package/plugin/skills/tools/document-processing/SKILL.md +916 -0
- package/plugin/skills/tools/image-processing/SKILL.md +748 -0
- package/plugin/skills/tools/mcp-development/SKILL.md +883 -0
- package/plugin/skills/tools/media-processing/SKILL.md +831 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monorepo-management
|
|
3
|
+
description: Enterprise monorepo patterns with Turborepo and Nx including task orchestration, caching, and CI/CD optimization
|
|
4
|
+
category: devops
|
|
5
|
+
triggers:
|
|
6
|
+
- monorepo
|
|
7
|
+
- turborepo
|
|
8
|
+
- nx
|
|
9
|
+
- workspace
|
|
10
|
+
- task orchestration
|
|
11
|
+
- build caching
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Monorepo Management
|
|
15
|
+
|
|
16
|
+
Master **monorepo architecture** with Turborepo and Nx. This skill covers workspace configuration, task orchestration, caching strategies, and CI/CD optimization for large-scale codebases.
|
|
17
|
+
|
|
18
|
+
## Purpose
|
|
19
|
+
|
|
20
|
+
Manage complex multi-package codebases efficiently:
|
|
21
|
+
|
|
22
|
+
- Configure workspace tooling and dependencies
|
|
23
|
+
- Orchestrate builds with optimal task scheduling
|
|
24
|
+
- Implement remote caching for faster builds
|
|
25
|
+
- Optimize CI/CD for affected packages only
|
|
26
|
+
- Share code and configurations across packages
|
|
27
|
+
- Scale to hundreds of packages
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
### 1. Turborepo Setup
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
// turbo.json - Pipeline configuration
|
|
35
|
+
{
|
|
36
|
+
"$schema": "https://turbo.build/schema.json",
|
|
37
|
+
"globalDependencies": [".env", "tsconfig.base.json"],
|
|
38
|
+
"globalEnv": ["NODE_ENV", "CI"],
|
|
39
|
+
"pipeline": {
|
|
40
|
+
"build": {
|
|
41
|
+
"dependsOn": ["^build"],
|
|
42
|
+
"outputs": ["dist/**", ".next/**", "build/**"],
|
|
43
|
+
"env": ["NODE_ENV"]
|
|
44
|
+
},
|
|
45
|
+
"test": {
|
|
46
|
+
"dependsOn": ["build"],
|
|
47
|
+
"outputs": ["coverage/**"],
|
|
48
|
+
"inputs": ["src/**/*.ts", "src/**/*.tsx", "tests/**"]
|
|
49
|
+
},
|
|
50
|
+
"lint": {
|
|
51
|
+
"outputs": []
|
|
52
|
+
},
|
|
53
|
+
"dev": {
|
|
54
|
+
"cache": false,
|
|
55
|
+
"persistent": true
|
|
56
|
+
},
|
|
57
|
+
"type-check": {
|
|
58
|
+
"dependsOn": ["^build"],
|
|
59
|
+
"outputs": []
|
|
60
|
+
},
|
|
61
|
+
"clean": {
|
|
62
|
+
"cache": false
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
# Project structure
|
|
70
|
+
my-monorepo/
|
|
71
|
+
├── apps/
|
|
72
|
+
│ ├── web/ # Next.js frontend
|
|
73
|
+
│ │ ├── package.json
|
|
74
|
+
│ │ └── ...
|
|
75
|
+
│ ├── api/ # Express backend
|
|
76
|
+
│ │ ├── package.json
|
|
77
|
+
│ │ └── ...
|
|
78
|
+
│ └── mobile/ # React Native app
|
|
79
|
+
│ ├── package.json
|
|
80
|
+
│ └── ...
|
|
81
|
+
├── packages/
|
|
82
|
+
│ ├── ui/ # Shared component library
|
|
83
|
+
│ │ ├── package.json
|
|
84
|
+
│ │ └── ...
|
|
85
|
+
│ ├── config/ # Shared configs
|
|
86
|
+
│ │ ├── eslint/
|
|
87
|
+
│ │ ├── typescript/
|
|
88
|
+
│ │ └── tailwind/
|
|
89
|
+
│ ├── database/ # Prisma schema & client
|
|
90
|
+
│ │ ├── package.json
|
|
91
|
+
│ │ └── ...
|
|
92
|
+
│ └── utils/ # Shared utilities
|
|
93
|
+
│ ├── package.json
|
|
94
|
+
│ └── ...
|
|
95
|
+
├── turbo.json
|
|
96
|
+
├── package.json
|
|
97
|
+
└── pnpm-workspace.yaml
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
# pnpm-workspace.yaml
|
|
102
|
+
packages:
|
|
103
|
+
- "apps/*"
|
|
104
|
+
- "packages/*"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 2. Nx Configuration
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
// nx.json
|
|
111
|
+
{
|
|
112
|
+
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
|
113
|
+
"targetDefaults": {
|
|
114
|
+
"build": {
|
|
115
|
+
"dependsOn": ["^build"],
|
|
116
|
+
"inputs": ["production", "^production"],
|
|
117
|
+
"cache": true
|
|
118
|
+
},
|
|
119
|
+
"test": {
|
|
120
|
+
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
|
|
121
|
+
"cache": true
|
|
122
|
+
},
|
|
123
|
+
"lint": {
|
|
124
|
+
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
|
|
125
|
+
"cache": true
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"namedInputs": {
|
|
129
|
+
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
|
130
|
+
"production": [
|
|
131
|
+
"default",
|
|
132
|
+
"!{projectRoot}/**/*.spec.ts",
|
|
133
|
+
"!{projectRoot}/jest.config.ts"
|
|
134
|
+
],
|
|
135
|
+
"sharedGlobals": [
|
|
136
|
+
"{workspaceRoot}/tsconfig.base.json",
|
|
137
|
+
"{workspaceRoot}/nx.json"
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
"parallel": 3,
|
|
141
|
+
"cacheDirectory": ".nx/cache",
|
|
142
|
+
"tasksRunnerOptions": {
|
|
143
|
+
"default": {
|
|
144
|
+
"runner": "nx/tasks-runners/default",
|
|
145
|
+
"options": {
|
|
146
|
+
"cacheableOperations": ["build", "test", "lint", "e2e"]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"affected": {
|
|
151
|
+
"defaultBase": "main"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
// project.json (per project)
|
|
158
|
+
{
|
|
159
|
+
"name": "web",
|
|
160
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
161
|
+
"projectType": "application",
|
|
162
|
+
"sourceRoot": "apps/web/src",
|
|
163
|
+
"targets": {
|
|
164
|
+
"build": {
|
|
165
|
+
"executor": "@nx/next:build",
|
|
166
|
+
"outputs": ["{options.outputPath}"],
|
|
167
|
+
"options": {
|
|
168
|
+
"outputPath": "dist/apps/web"
|
|
169
|
+
},
|
|
170
|
+
"configurations": {
|
|
171
|
+
"production": {
|
|
172
|
+
"outputPath": "dist/apps/web"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"serve": {
|
|
177
|
+
"executor": "@nx/next:server",
|
|
178
|
+
"options": {
|
|
179
|
+
"buildTarget": "web:build",
|
|
180
|
+
"dev": true
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"test": {
|
|
184
|
+
"executor": "@nx/jest:jest",
|
|
185
|
+
"outputs": ["{workspaceRoot}/coverage/apps/web"],
|
|
186
|
+
"options": {
|
|
187
|
+
"jestConfig": "apps/web/jest.config.ts"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"tags": ["type:app", "scope:web"]
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 3. Task Orchestration
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// scripts/orchestrate.ts
|
|
199
|
+
import { execSync, spawn } from 'child_process';
|
|
200
|
+
|
|
201
|
+
interface TaskConfig {
|
|
202
|
+
name: string;
|
|
203
|
+
command: string;
|
|
204
|
+
dependsOn?: string[];
|
|
205
|
+
parallel?: boolean;
|
|
206
|
+
cwd?: string;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Topological sort for dependency resolution
|
|
210
|
+
function topologicalSort(tasks: Map<string, TaskConfig>): string[] {
|
|
211
|
+
const visited = new Set<string>();
|
|
212
|
+
const result: string[] = [];
|
|
213
|
+
|
|
214
|
+
function visit(name: string) {
|
|
215
|
+
if (visited.has(name)) return;
|
|
216
|
+
visited.add(name);
|
|
217
|
+
|
|
218
|
+
const task = tasks.get(name);
|
|
219
|
+
if (task?.dependsOn) {
|
|
220
|
+
for (const dep of task.dependsOn) {
|
|
221
|
+
visit(dep);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
result.push(name);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
for (const name of tasks.keys()) {
|
|
228
|
+
visit(name);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Execute tasks with concurrency control
|
|
235
|
+
async function runTasks(
|
|
236
|
+
taskNames: string[],
|
|
237
|
+
tasks: Map<string, TaskConfig>,
|
|
238
|
+
concurrency: number = 4
|
|
239
|
+
): Promise<void> {
|
|
240
|
+
const sorted = topologicalSort(tasks);
|
|
241
|
+
const filtered = sorted.filter(t => taskNames.includes(t) || taskNames.length === 0);
|
|
242
|
+
|
|
243
|
+
const running = new Map<string, Promise<void>>();
|
|
244
|
+
const completed = new Set<string>();
|
|
245
|
+
|
|
246
|
+
for (const name of filtered) {
|
|
247
|
+
const task = tasks.get(name)!;
|
|
248
|
+
|
|
249
|
+
// Wait for dependencies
|
|
250
|
+
if (task.dependsOn) {
|
|
251
|
+
await Promise.all(
|
|
252
|
+
task.dependsOn
|
|
253
|
+
.filter(dep => running.has(dep))
|
|
254
|
+
.map(dep => running.get(dep))
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Wait if at concurrency limit
|
|
259
|
+
while (running.size >= concurrency) {
|
|
260
|
+
await Promise.race(running.values());
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Start task
|
|
264
|
+
const promise = runTask(task).then(() => {
|
|
265
|
+
completed.add(name);
|
|
266
|
+
running.delete(name);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
running.set(name, promise);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Wait for all to complete
|
|
273
|
+
await Promise.all(running.values());
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function runTask(task: TaskConfig): Promise<void> {
|
|
277
|
+
console.log(`Starting: ${task.name}`);
|
|
278
|
+
const startTime = Date.now();
|
|
279
|
+
|
|
280
|
+
return new Promise((resolve, reject) => {
|
|
281
|
+
const proc = spawn('sh', ['-c', task.command], {
|
|
282
|
+
cwd: task.cwd || process.cwd(),
|
|
283
|
+
stdio: 'inherit',
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
proc.on('close', (code) => {
|
|
287
|
+
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
288
|
+
if (code === 0) {
|
|
289
|
+
console.log(`✓ ${task.name} (${duration}s)`);
|
|
290
|
+
resolve();
|
|
291
|
+
} else {
|
|
292
|
+
console.error(`✗ ${task.name} failed`);
|
|
293
|
+
reject(new Error(`Task ${task.name} exited with code ${code}`));
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 4. Remote Caching
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// Turborepo remote cache setup
|
|
304
|
+
// turbo.json
|
|
305
|
+
{
|
|
306
|
+
"remoteCache": {
|
|
307
|
+
"signature": true
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Environment variables
|
|
312
|
+
// TURBO_TOKEN=your_token
|
|
313
|
+
// TURBO_TEAM=your_team
|
|
314
|
+
// TURBO_REMOTE_ONLY=true (optional)
|
|
315
|
+
|
|
316
|
+
// Custom cache handler
|
|
317
|
+
// .turbo/config.json
|
|
318
|
+
{
|
|
319
|
+
"teamId": "team_xxx",
|
|
320
|
+
"apiUrl": "https://cache.example.com"
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Self-hosted cache server
|
|
324
|
+
import express from 'express';
|
|
325
|
+
import { createHash } from 'crypto';
|
|
326
|
+
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
327
|
+
|
|
328
|
+
const app = express();
|
|
329
|
+
const s3 = new S3Client({ region: process.env.AWS_REGION });
|
|
330
|
+
|
|
331
|
+
// PUT artifact
|
|
332
|
+
app.put('/v8/artifacts/:hash', async (req, res) => {
|
|
333
|
+
const { hash } = req.params;
|
|
334
|
+
const teamId = req.headers['x-artifact-client-ci'];
|
|
335
|
+
|
|
336
|
+
const chunks: Buffer[] = [];
|
|
337
|
+
for await (const chunk of req) {
|
|
338
|
+
chunks.push(chunk);
|
|
339
|
+
}
|
|
340
|
+
const body = Buffer.concat(chunks);
|
|
341
|
+
|
|
342
|
+
await s3.send(new PutObjectCommand({
|
|
343
|
+
Bucket: process.env.CACHE_BUCKET,
|
|
344
|
+
Key: `${teamId}/${hash}`,
|
|
345
|
+
Body: body,
|
|
346
|
+
}));
|
|
347
|
+
|
|
348
|
+
res.status(200).json({ success: true });
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// GET artifact
|
|
352
|
+
app.get('/v8/artifacts/:hash', async (req, res) => {
|
|
353
|
+
const { hash } = req.params;
|
|
354
|
+
const teamId = req.headers['x-artifact-client-ci'];
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
const response = await s3.send(new GetObjectCommand({
|
|
358
|
+
Bucket: process.env.CACHE_BUCKET,
|
|
359
|
+
Key: `${teamId}/${hash}`,
|
|
360
|
+
}));
|
|
361
|
+
|
|
362
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
363
|
+
response.Body?.pipe(res);
|
|
364
|
+
} catch {
|
|
365
|
+
res.status(404).json({ error: 'Not found' });
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
app.listen(3000);
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 5. CI/CD Optimization
|
|
373
|
+
|
|
374
|
+
```yaml
|
|
375
|
+
# .github/workflows/ci.yml
|
|
376
|
+
name: CI
|
|
377
|
+
|
|
378
|
+
on:
|
|
379
|
+
push:
|
|
380
|
+
branches: [main]
|
|
381
|
+
pull_request:
|
|
382
|
+
branches: [main]
|
|
383
|
+
|
|
384
|
+
env:
|
|
385
|
+
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
386
|
+
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
|
387
|
+
|
|
388
|
+
jobs:
|
|
389
|
+
build:
|
|
390
|
+
runs-on: ubuntu-latest
|
|
391
|
+
steps:
|
|
392
|
+
- uses: actions/checkout@v4
|
|
393
|
+
with:
|
|
394
|
+
fetch-depth: 0 # Full history for affected detection
|
|
395
|
+
|
|
396
|
+
- uses: pnpm/action-setup@v2
|
|
397
|
+
with:
|
|
398
|
+
version: 8
|
|
399
|
+
|
|
400
|
+
- uses: actions/setup-node@v4
|
|
401
|
+
with:
|
|
402
|
+
node-version: 20
|
|
403
|
+
cache: 'pnpm'
|
|
404
|
+
|
|
405
|
+
- name: Install dependencies
|
|
406
|
+
run: pnpm install --frozen-lockfile
|
|
407
|
+
|
|
408
|
+
# Only run affected packages
|
|
409
|
+
- name: Build affected packages
|
|
410
|
+
run: pnpm turbo build --filter='...[origin/main]'
|
|
411
|
+
|
|
412
|
+
- name: Test affected packages
|
|
413
|
+
run: pnpm turbo test --filter='...[origin/main]'
|
|
414
|
+
|
|
415
|
+
- name: Lint affected packages
|
|
416
|
+
run: pnpm turbo lint --filter='...[origin/main]'
|
|
417
|
+
|
|
418
|
+
deploy-preview:
|
|
419
|
+
needs: build
|
|
420
|
+
if: github.event_name == 'pull_request'
|
|
421
|
+
runs-on: ubuntu-latest
|
|
422
|
+
steps:
|
|
423
|
+
- uses: actions/checkout@v4
|
|
424
|
+
- uses: pnpm/action-setup@v2
|
|
425
|
+
- uses: actions/setup-node@v4
|
|
426
|
+
with:
|
|
427
|
+
node-version: 20
|
|
428
|
+
cache: 'pnpm'
|
|
429
|
+
|
|
430
|
+
- run: pnpm install --frozen-lockfile
|
|
431
|
+
|
|
432
|
+
# Deploy only changed apps
|
|
433
|
+
- name: Deploy preview
|
|
434
|
+
run: |
|
|
435
|
+
CHANGED=$(pnpm turbo build --filter='...[origin/main]' --dry-run=json | jq -r '.packages[]')
|
|
436
|
+
for app in $CHANGED; do
|
|
437
|
+
if [[ $app == apps/* ]]; then
|
|
438
|
+
pnpm turbo deploy --filter=$app
|
|
439
|
+
fi
|
|
440
|
+
done
|
|
441
|
+
|
|
442
|
+
deploy-production:
|
|
443
|
+
needs: build
|
|
444
|
+
if: github.ref == 'refs/heads/main'
|
|
445
|
+
runs-on: ubuntu-latest
|
|
446
|
+
steps:
|
|
447
|
+
- uses: actions/checkout@v4
|
|
448
|
+
- uses: pnpm/action-setup@v2
|
|
449
|
+
- uses: actions/setup-node@v4
|
|
450
|
+
with:
|
|
451
|
+
node-version: 20
|
|
452
|
+
cache: 'pnpm'
|
|
453
|
+
|
|
454
|
+
- run: pnpm install --frozen-lockfile
|
|
455
|
+
- run: pnpm turbo build
|
|
456
|
+
- run: pnpm turbo deploy
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### 6. Shared Configurations
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
// packages/config/eslint/index.js
|
|
463
|
+
module.exports = {
|
|
464
|
+
extends: [
|
|
465
|
+
'eslint:recommended',
|
|
466
|
+
'plugin:@typescript-eslint/recommended',
|
|
467
|
+
'prettier',
|
|
468
|
+
],
|
|
469
|
+
parser: '@typescript-eslint/parser',
|
|
470
|
+
plugins: ['@typescript-eslint'],
|
|
471
|
+
rules: {
|
|
472
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
473
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
474
|
+
},
|
|
475
|
+
ignorePatterns: ['dist', 'node_modules', '.turbo'],
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// packages/config/eslint/react.js
|
|
479
|
+
module.exports = {
|
|
480
|
+
extends: [
|
|
481
|
+
'./index.js',
|
|
482
|
+
'plugin:react/recommended',
|
|
483
|
+
'plugin:react-hooks/recommended',
|
|
484
|
+
],
|
|
485
|
+
plugins: ['react', 'react-hooks'],
|
|
486
|
+
settings: {
|
|
487
|
+
react: { version: 'detect' },
|
|
488
|
+
},
|
|
489
|
+
rules: {
|
|
490
|
+
'react/react-in-jsx-scope': 'off',
|
|
491
|
+
'react/prop-types': 'off',
|
|
492
|
+
},
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
// packages/config/typescript/base.json
|
|
496
|
+
{
|
|
497
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
498
|
+
"compilerOptions": {
|
|
499
|
+
"target": "ES2022",
|
|
500
|
+
"lib": ["ES2022"],
|
|
501
|
+
"module": "ESNext",
|
|
502
|
+
"moduleResolution": "bundler",
|
|
503
|
+
"strict": true,
|
|
504
|
+
"skipLibCheck": true,
|
|
505
|
+
"declaration": true,
|
|
506
|
+
"declarationMap": true,
|
|
507
|
+
"sourceMap": true,
|
|
508
|
+
"esModuleInterop": true,
|
|
509
|
+
"resolveJsonModule": true,
|
|
510
|
+
"isolatedModules": true,
|
|
511
|
+
"noEmit": true
|
|
512
|
+
},
|
|
513
|
+
"exclude": ["node_modules", "dist"]
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// packages/config/typescript/react.json
|
|
517
|
+
{
|
|
518
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
519
|
+
"extends": "./base.json",
|
|
520
|
+
"compilerOptions": {
|
|
521
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
522
|
+
"jsx": "react-jsx"
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Use Cases
|
|
528
|
+
|
|
529
|
+
### 1. Multi-App Platform
|
|
530
|
+
|
|
531
|
+
```
|
|
532
|
+
# Build and deploy specific apps
|
|
533
|
+
pnpm turbo build --filter=web --filter=api
|
|
534
|
+
|
|
535
|
+
# Run dev for specific app with dependencies
|
|
536
|
+
pnpm turbo dev --filter=web...
|
|
537
|
+
|
|
538
|
+
# Test only affected by changes
|
|
539
|
+
pnpm turbo test --filter='...[HEAD~1]'
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 2. Component Library Publishing
|
|
543
|
+
|
|
544
|
+
```json
|
|
545
|
+
// packages/ui/package.json
|
|
546
|
+
{
|
|
547
|
+
"name": "@myorg/ui",
|
|
548
|
+
"version": "1.0.0",
|
|
549
|
+
"main": "./dist/index.js",
|
|
550
|
+
"types": "./dist/index.d.ts",
|
|
551
|
+
"exports": {
|
|
552
|
+
".": {
|
|
553
|
+
"import": "./dist/index.mjs",
|
|
554
|
+
"require": "./dist/index.js"
|
|
555
|
+
},
|
|
556
|
+
"./styles.css": "./dist/styles.css"
|
|
557
|
+
},
|
|
558
|
+
"scripts": {
|
|
559
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
560
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
## Best Practices
|
|
566
|
+
|
|
567
|
+
### Do's
|
|
568
|
+
|
|
569
|
+
- **Use remote caching** - Dramatically speeds up CI
|
|
570
|
+
- **Define clear package boundaries** - Single responsibility
|
|
571
|
+
- **Run affected only** - Don't rebuild unchanged packages
|
|
572
|
+
- **Share configurations** - Consistent tooling
|
|
573
|
+
- **Use workspace protocol** - `workspace:*` for internal deps
|
|
574
|
+
- **Document dependency graph** - Keep architecture clear
|
|
575
|
+
|
|
576
|
+
### Don'ts
|
|
577
|
+
|
|
578
|
+
- Don't create circular dependencies
|
|
579
|
+
- Don't skip input/output definitions
|
|
580
|
+
- Don't ignore cache invalidation
|
|
581
|
+
- Don't duplicate configurations
|
|
582
|
+
- Don't over-share packages
|
|
583
|
+
- Don't skip CI optimization
|
|
584
|
+
|
|
585
|
+
## Related Skills
|
|
586
|
+
|
|
587
|
+
- **github-actions** - CI/CD pipelines
|
|
588
|
+
- **docker** - Containerization
|
|
589
|
+
- **typescript** - Type-safe development
|
|
590
|
+
|
|
591
|
+
## Reference Resources
|
|
592
|
+
|
|
593
|
+
- [Turborepo Documentation](https://turbo.build/repo/docs)
|
|
594
|
+
- [Nx Documentation](https://nx.dev/getting-started/intro)
|
|
595
|
+
- [pnpm Workspaces](https://pnpm.io/workspaces)
|