@codedrifters/configulator 0.0.75 → 0.0.77
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/LICENSE +1 -1
- package/README.md +570 -159
- package/lib/aws/aws-deployment-config.js +11 -11
- package/lib/aws/aws-deployment-target.d.ts +1 -44
- package/lib/aws/aws-deployment-target.js +7 -49
- package/lib/pnpm/pnpm-workspace.d.ts +85 -0
- package/lib/pnpm/pnpm-workspace.js +22 -1
- package/lib/projects/monorepo-project.js +14 -7
- package/lib/projects/typescript-project.js +56 -7
- package/lib/versions.d.ts +4 -4
- package/lib/versions.js +5 -5
- package/lib/workflows/aws-deploy-workflow.d.ts +2 -1
- package/lib/workflows/aws-deploy-workflow.js +4 -4
- package/package.json +7 -9
- package/.jsii +0 -23
package/README.md
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Configulator
|
|
2
|
+
|
|
3
|
+
A library of [Projen](https://projen.io/) components used by CodeDrifters to manage repository configuration across various projects. Configulator extends standard Projen configurations with our preferred defaults and provides company-specific components and workflows.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Overview](#overview)
|
|
8
|
+
- [What is Projen?](#what-is-projen)
|
|
9
|
+
- [What is Configulator?](#what-is-configulator)
|
|
10
|
+
- [Project Types](#project-types)
|
|
11
|
+
- [MonorepoProject](#monorepoproject)
|
|
12
|
+
- [TypeScriptProject](#typescriptproject)
|
|
13
|
+
- [Usage Patterns](#usage-patterns)
|
|
14
|
+
- [Configuration Options](#configuration-options)
|
|
15
|
+
- [Turbo Repo](#turbo-repo)
|
|
16
|
+
- [PNPM Workspace](#pnpm-workspace)
|
|
17
|
+
- [File Management Rules](#file-management-rules)
|
|
18
|
+
- [Workflow Tips](#workflow-tips)
|
|
19
|
+
- [API Reference](#api-reference)
|
|
20
|
+
- [Troubleshooting](#troubleshooting)
|
|
21
|
+
- [Additional Resources](#additional-resources)
|
|
2
22
|
|
|
3
23
|
## Overview
|
|
4
24
|
|
|
@@ -23,11 +43,10 @@ Projen is a project generator and configuration management tool that:
|
|
|
23
43
|
|
|
24
44
|
## What is Configulator?
|
|
25
45
|
|
|
26
|
-
|
|
46
|
+
Configulator is CodeDrifters' custom extension of Projen. It:
|
|
27
47
|
|
|
28
48
|
- Extends standard Projen configurations with our preferred defaults
|
|
29
49
|
- Provides company-specific components and workflows
|
|
30
|
-
- Currently at version 0.48 (alpha/internal use)
|
|
31
50
|
- Available as an npm package: `@codedrifters/configulator`
|
|
32
51
|
|
|
33
52
|
### Why We Built It
|
|
@@ -39,84 +58,454 @@ Instead of setting up each new project from scratch (90% identical setup repeate
|
|
|
39
58
|
- Maintain standardized tooling across all projects
|
|
40
59
|
- Receive updates to common configurations automatically
|
|
41
60
|
|
|
42
|
-
##
|
|
61
|
+
## Project Types
|
|
43
62
|
|
|
44
|
-
|
|
63
|
+
Configulator provides two main project types designed for monorepo workflows:
|
|
45
64
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
### MonorepoProject
|
|
66
|
+
|
|
67
|
+
**MonorepoProject** extends Projen's `TypeScriptAppProject` and is designed specifically for monorepo root projects. It provides all the infrastructure needed to manage a monorepo with multiple sub-projects.
|
|
68
|
+
|
|
69
|
+
#### When to Use It
|
|
49
70
|
|
|
50
|
-
|
|
71
|
+
Use `MonorepoProject` for:
|
|
72
|
+
- Root-level monorepo configuration
|
|
73
|
+
- Managing workspace-wide settings (PNPM, Turborepo, VS Code)
|
|
74
|
+
- Defining shared dependency catalogs
|
|
75
|
+
- Configuring build workflows for the entire monorepo
|
|
51
76
|
|
|
52
|
-
|
|
53
|
-
- Prettier for code formatting
|
|
54
|
-
- VS Code settings
|
|
55
|
-
- GitHub workflows (build, PR checks)
|
|
56
|
-
- Weekly dependency upgrade workflow
|
|
77
|
+
#### Key Features
|
|
57
78
|
|
|
58
|
-
|
|
79
|
+
- **PNPM Workspace Management**: Automatically generates and manages `pnpm-workspace.yaml`
|
|
80
|
+
- **Turborepo Integration**: Built-in support for Turborepo with remote caching capabilities
|
|
81
|
+
- **VS Code Configuration**: Automatic VS Code settings for consistent development experience
|
|
82
|
+
- **Default Catalog**: Pre-configured catalog of common dependency versions (AWS CDK, Projen, Constructs, Turbo)
|
|
83
|
+
- **Build Workflow Configuration**: GitHub Actions workflows with Turborepo support
|
|
84
|
+
- **TypeScript Configuration**: Pre-configured TypeScript with sensible defaults
|
|
59
85
|
|
|
60
|
-
|
|
86
|
+
#### Basic Example
|
|
61
87
|
|
|
62
88
|
```typescript
|
|
63
|
-
import { MonorepoProject } from '@codedrifters/
|
|
89
|
+
import { MonorepoProject } from '@codedrifters/configulator';
|
|
64
90
|
|
|
65
91
|
const project = new MonorepoProject({
|
|
66
|
-
name: 'my-
|
|
92
|
+
name: 'my-monorepo'
|
|
67
93
|
});
|
|
68
94
|
|
|
69
95
|
project.synth();
|
|
70
96
|
```
|
|
71
97
|
|
|
72
|
-
|
|
98
|
+
#### Advanced Example with Remote Cache
|
|
73
99
|
|
|
74
|
-
|
|
100
|
+
```typescript
|
|
101
|
+
import { MonorepoProject } from '@codedrifters/configulator';
|
|
75
102
|
|
|
76
|
-
|
|
103
|
+
const project = new MonorepoProject({
|
|
104
|
+
name: 'my-monorepo',
|
|
105
|
+
|
|
106
|
+
turboOptions: {
|
|
107
|
+
remoteCacheOptions: {
|
|
108
|
+
profileName: 'profile-prod-000000000000-us-east-1',
|
|
109
|
+
oidcRole: 'arn:aws:iam::000000000000:role/TurborepoRemoteCachingRole',
|
|
110
|
+
endpointParamName: '/TURBOREPO/ENDPOINT/PARAMETER',
|
|
111
|
+
tokenParamName: '/TURBOREPO/TOKEN/PARAMETER',
|
|
112
|
+
teamName: 'prod',
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
pnpmOptions: {
|
|
117
|
+
pnpmWorkspaceOptions: {
|
|
118
|
+
onlyBuiltDependencies: ['@swc/core', 'esbuild', 'unrs-resolver'],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
77
122
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
- Build scripts
|
|
81
|
-
- Most files listed in `.projen/files.json`
|
|
123
|
+
project.synth();
|
|
124
|
+
```
|
|
82
125
|
|
|
83
|
-
|
|
126
|
+
#### Configuration Options
|
|
84
127
|
|
|
85
|
-
`
|
|
128
|
+
The `MonorepoProject` accepts all options from `TypeScriptProjectOptions` plus:
|
|
86
129
|
|
|
87
|
-
|
|
130
|
+
| Option | Type | Default | Description |
|
|
131
|
+
|--------|------|---------|-------------|
|
|
132
|
+
| `name` | `string` | **Required** | Project name |
|
|
133
|
+
| `turbo` | `boolean` | `true` | Enable Turborepo support |
|
|
134
|
+
| `turboOptions` | `TurboRepoOptions` | `undefined` | Turborepo configuration including remote cache options |
|
|
135
|
+
| `pnpmOptions.version` | `string` | `VERSION.PNPM_VERSION` | PNPM version to use |
|
|
136
|
+
| `pnpmOptions.pnpmWorkspaceOptions` | `PnpmWorkspaceOptions` | See below | PNPM workspace configuration |
|
|
88
137
|
|
|
89
|
-
**
|
|
90
|
-
|
|
91
|
-
|
|
138
|
+
**Default Behavior:**
|
|
139
|
+
- `projenrcTs: true` - Uses TypeScript for projen configuration
|
|
140
|
+
- `prettier: true` - Enables Prettier formatting
|
|
141
|
+
- `licensed: false` - No license by default
|
|
142
|
+
- `sampleCode: false` - No sample code generated
|
|
143
|
+
- `jest: false` - Jest disabled at root level
|
|
144
|
+
- `release: false` - Root project is not released
|
|
145
|
+
- `depsUpgrade: false` - No automatic dependency upgrades at root
|
|
146
|
+
- `disableTsconfigDev: true` - No tsconfig.dev.json at root
|
|
147
|
+
- `packageManager: NodePackageManager.PNPM` - PNPM is mandatory
|
|
148
|
+
- `defaultReleaseBranch: "main"` - Standard branch name
|
|
149
|
+
|
|
150
|
+
The root project automatically includes `@codedrifters/configulator` and `constructs` as dev dependencies.
|
|
151
|
+
|
|
152
|
+
### TypeScriptProject
|
|
153
|
+
|
|
154
|
+
**TypeScriptProject** extends Projen's `TypeScriptProject` with CodeDrifters defaults. It's designed for sub-projects within a monorepo or standalone TypeScript projects.
|
|
155
|
+
|
|
156
|
+
#### When to Use It
|
|
157
|
+
|
|
158
|
+
Use `TypeScriptProject` for:
|
|
159
|
+
- Sub-projects within a monorepo (most common use case)
|
|
160
|
+
- Standalone TypeScript libraries or applications
|
|
161
|
+
- Packages that will be published to NPM
|
|
162
|
+
- Projects that need consistent testing, linting, and build configuration
|
|
163
|
+
|
|
164
|
+
#### Key Features
|
|
165
|
+
|
|
166
|
+
- **Automatic PNPM Version Inheritance**: Inherits PNPM version from parent `MonorepoProject` when used as a sub-project
|
|
167
|
+
- **SWC for Testing**: Uses `@swc/jest` instead of `ts-jest` for faster test execution
|
|
168
|
+
- **Prettier Integration**: Automatic Prettier configuration
|
|
169
|
+
- **Jest Configuration**: External Jest config file (not in package.json) with sensible defaults
|
|
170
|
+
- **Automatic Turborepo Integration**: Automatically configures Turborepo tasks when parent has TurboRepo enabled
|
|
171
|
+
- **Catalog Dependency Support**: Can use catalog dependencies defined in parent workspace
|
|
172
|
+
- **Release Support**: Built-in support for NPM releases with continuous deployment triggers
|
|
173
|
+
|
|
174
|
+
#### Basic Example
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
|
|
178
|
+
|
|
179
|
+
// Root project
|
|
180
|
+
const root = new MonorepoProject({
|
|
181
|
+
name: 'my-monorepo'
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Sub-project
|
|
185
|
+
const myPackage = new TypeScriptProject({
|
|
186
|
+
name: 'my-package',
|
|
187
|
+
packageName: '@myorg/my-package',
|
|
188
|
+
outdir: 'packages/my-package',
|
|
189
|
+
parent: root,
|
|
190
|
+
description: 'My awesome package',
|
|
191
|
+
deps: ['some-dependency'],
|
|
192
|
+
devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
root.synth();
|
|
92
196
|
```
|
|
93
197
|
|
|
94
|
-
|
|
198
|
+
#### Example with Release Configuration
|
|
95
199
|
|
|
96
|
-
|
|
200
|
+
```typescript
|
|
201
|
+
import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
|
|
97
202
|
|
|
98
|
-
|
|
203
|
+
const root = new MonorepoProject({
|
|
204
|
+
name: 'my-monorepo'
|
|
205
|
+
});
|
|
99
206
|
|
|
207
|
+
const constructs = new TypeScriptProject({
|
|
208
|
+
name: '@codedrifters/constructs',
|
|
209
|
+
packageName: '@codedrifters/constructs',
|
|
210
|
+
outdir: 'packages/@codedrifters/constructs',
|
|
211
|
+
description: 'Constructs frequently used in CodeDrifter projects.',
|
|
212
|
+
repository: 'https://github.com/codedrifters/packages',
|
|
213
|
+
authorName: 'CodeDrifters',
|
|
214
|
+
authorOrganization: true,
|
|
215
|
+
licensed: false,
|
|
216
|
+
parent: root,
|
|
217
|
+
|
|
218
|
+
deps: [
|
|
219
|
+
'@aws-sdk/client-dynamodb',
|
|
220
|
+
'@types/aws-lambda',
|
|
221
|
+
'change-case@^4.0',
|
|
222
|
+
'type-fest@^4',
|
|
223
|
+
],
|
|
224
|
+
devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
225
|
+
peerDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
226
|
+
|
|
227
|
+
release: true,
|
|
228
|
+
releaseToNpm: true,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
root.synth();
|
|
100
232
|
```
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
233
|
+
|
|
234
|
+
#### Parent-Child Relationship
|
|
235
|
+
|
|
236
|
+
When `TypeScriptProject` is created with a `parent` that is a `MonorepoProject`:
|
|
237
|
+
|
|
238
|
+
1. **PNPM Version**: Automatically inherits the PNPM version from the parent
|
|
239
|
+
2. **Workspace Integration**: Automatically added to the parent's PNPM workspace
|
|
240
|
+
3. **Turborepo Integration**: If parent has Turborepo enabled, the sub-project automatically gets Turborepo task configuration
|
|
241
|
+
4. **Catalog Dependencies**: Can reference catalog dependencies defined in the parent's workspace
|
|
242
|
+
5. **Dependency Upgrade Exclusions**: Automatically excludes catalog-managed dependencies from upgrade workflows
|
|
243
|
+
|
|
244
|
+
#### Configuration Options
|
|
245
|
+
|
|
246
|
+
The `TypeScriptProject` accepts all options from Projen's `TypeScriptProjectOptions` with these defaults:
|
|
247
|
+
|
|
248
|
+
| Option | Type | Default | Description |
|
|
249
|
+
|--------|------|---------|-------------|
|
|
250
|
+
| `name` | `string` | **Required** | Project name |
|
|
251
|
+
| `packageName` | `string` | Same as `name` | NPM package name |
|
|
252
|
+
| `outdir` | `string` | `"."` | Output directory (required for sub-projects) |
|
|
253
|
+
| `parent` | `MonorepoProject` | `undefined` | Parent monorepo project (recommended) |
|
|
254
|
+
| `defaultReleaseBranch` | `string` | `"main"` | Default release branch |
|
|
255
|
+
| `packageManager` | `NodePackageManager` | `PNPM` | Package manager (always PNPM) |
|
|
256
|
+
| `prettier` | `boolean` | `true` | Enable Prettier |
|
|
257
|
+
| `sampleCode` | `boolean` | `false` | Generate sample code |
|
|
258
|
+
| `release` | `boolean` | `false` | Enable NPM releases |
|
|
259
|
+
| `licensed` | `boolean` | `false` | Include license (unless `license` option provided) |
|
|
260
|
+
|
|
261
|
+
**Jest Configuration:**
|
|
262
|
+
- Uses external `jest.config.json` file
|
|
263
|
+
- Configured to use `@swc/jest` for faster compilation
|
|
264
|
+
- Test files in `src/` directory
|
|
265
|
+
- ESLint rule `import/no-extraneous-dependencies` disabled for test files
|
|
266
|
+
|
|
267
|
+
**NPM Ignore:**
|
|
268
|
+
- Automatically ignores `*.spec.*`, `*.test.*`, and `__fixtures__` patterns
|
|
269
|
+
|
|
270
|
+
**Release Configuration:**
|
|
271
|
+
- Uses continuous release trigger
|
|
272
|
+
- Only releases when package directory content changes
|
|
273
|
+
- Release path based on `outdir`
|
|
274
|
+
|
|
275
|
+
## Usage Patterns
|
|
276
|
+
|
|
277
|
+
### Monorepo Setup Pattern
|
|
278
|
+
|
|
279
|
+
The most common pattern is to create a monorepo with a root project and multiple sub-projects:
|
|
280
|
+
|
|
281
|
+
1. **Create the root project** using `MonorepoProject`:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// projenrc/root-project.ts
|
|
285
|
+
import { MonorepoProject } from '@codedrifters/configulator';
|
|
286
|
+
|
|
287
|
+
export const configureRootProject = () => {
|
|
288
|
+
const project = new MonorepoProject({
|
|
289
|
+
name: 'my-monorepo',
|
|
290
|
+
turboOptions: {
|
|
291
|
+
remoteCacheOptions: {
|
|
292
|
+
profileName: 'my-profile',
|
|
293
|
+
oidcRole: 'arn:aws:iam::123456789012:role/TurborepoRole',
|
|
294
|
+
endpointParamName: '/TURBOREPO/ENDPOINT',
|
|
295
|
+
tokenParamName: '/TURBOREPO/TOKEN',
|
|
296
|
+
teamName: 'my-team',
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return project;
|
|
302
|
+
};
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
2. **Add sub-projects** using `TypeScriptProject`:
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// projenrc/my-package.ts
|
|
309
|
+
import { MonorepoProject } from '@codedrifters/configulator';
|
|
310
|
+
import { TypeScriptProject } from '@codedrifters/configulator';
|
|
311
|
+
|
|
312
|
+
export const configureMyPackage = (parent: MonorepoProject) => {
|
|
313
|
+
const myPackage = new TypeScriptProject({
|
|
314
|
+
name: 'my-package',
|
|
315
|
+
packageName: '@myorg/my-package',
|
|
316
|
+
outdir: 'packages/my-package',
|
|
317
|
+
description: 'My package description',
|
|
318
|
+
parent,
|
|
319
|
+
deps: ['dependency-1', 'dependency-2'],
|
|
320
|
+
devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
return { myPackage };
|
|
324
|
+
};
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
3. **Wire everything together** in your main projenrc file:
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// .projenrc.ts or projenrc/index.ts
|
|
331
|
+
import { configureRootProject } from './projenrc/root-project';
|
|
332
|
+
import { configureMyPackage } from './projenrc/my-package';
|
|
333
|
+
|
|
334
|
+
const root = configureRootProject();
|
|
335
|
+
const { myPackage } = configureMyPackage(root);
|
|
336
|
+
|
|
337
|
+
root.synth();
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Standalone Project Pattern
|
|
341
|
+
|
|
342
|
+
You can also use `TypeScriptProject` without a parent for standalone projects:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { TypeScriptProject } from '@codedrifters/configulator';
|
|
346
|
+
|
|
347
|
+
const project = new TypeScriptProject({
|
|
348
|
+
name: 'standalone-project',
|
|
349
|
+
packageName: '@myorg/standalone-project',
|
|
350
|
+
description: 'A standalone TypeScript project',
|
|
351
|
+
deps: ['some-dependency'],
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
project.synth();
|
|
106
355
|
```
|
|
107
356
|
|
|
108
|
-
|
|
357
|
+
Note: Without a parent, the project will use the default PNPM version from Configulator's version constants.
|
|
358
|
+
|
|
359
|
+
### Dependency Management
|
|
360
|
+
|
|
361
|
+
> **⚠️ Important:** All dependencies must be configured through Projen configuration files (`.projenrc.ts` or `projenrc/*.ts`), never by manually running package manager commands like `npm install`, `pnpm add`, or `yarn add`. Manual installation will create conflicts with Projen-managed files and may be overwritten when you run `npx projen`.
|
|
362
|
+
|
|
363
|
+
#### Using Catalog Dependencies
|
|
364
|
+
|
|
365
|
+
The `MonorepoProject` automatically sets up a default catalog with common dependencies:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Defined in MonorepoProject defaults
|
|
369
|
+
defaultCatalog: {
|
|
370
|
+
'aws-cdk': VERSION.AWS_CDK_CLI_VERSION,
|
|
371
|
+
'aws-cdk-lib': VERSION.AWS_CDK_LIB_VERSION,
|
|
372
|
+
'projen': VERSION.PROJEN_VERSION,
|
|
373
|
+
'constructs': VERSION.AWS_CONSTRUCTS_VERSION,
|
|
374
|
+
'turbo': VERSION.TURBO_VERSION,
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Sub-projects can reference these using the `catalog:` protocol:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
const myPackage = new TypeScriptProject({
|
|
382
|
+
// ... other options
|
|
383
|
+
devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
384
|
+
peerDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
|
|
385
|
+
});
|
|
386
|
+
```
|
|
109
387
|
|
|
110
|
-
|
|
388
|
+
#### Workspace Dependencies
|
|
111
389
|
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
390
|
+
Sub-projects can depend on other packages in the same monorepo:
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const packageB = new TypeScriptProject({
|
|
394
|
+
// ... other options
|
|
395
|
+
deps: ['@myorg/package-a@workspace:*'],
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### Custom Catalog
|
|
400
|
+
|
|
401
|
+
You can also define custom catalogs in the `MonorepoProject`:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
const root = new MonorepoProject({
|
|
405
|
+
name: 'my-monorepo',
|
|
406
|
+
pnpmOptions: {
|
|
407
|
+
pnpmWorkspaceOptions: {
|
|
408
|
+
defaultCatalog: {
|
|
409
|
+
'react': '^18.0.0',
|
|
410
|
+
'typescript': '^5.0.0',
|
|
411
|
+
},
|
|
412
|
+
namedCatalogs: {
|
|
413
|
+
frontend: {
|
|
414
|
+
'react': '^18.0.0',
|
|
415
|
+
'react-dom': '^18.0.0',
|
|
416
|
+
},
|
|
417
|
+
backend: {
|
|
418
|
+
'express': '^4.18.0',
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Then reference them in sub-projects:
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// Default catalog
|
|
430
|
+
deps: ['react@catalog:react']
|
|
431
|
+
|
|
432
|
+
// Named catalog
|
|
433
|
+
deps: ['react@catalog:frontend/react']
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Turborepo Integration
|
|
437
|
+
|
|
438
|
+
When you create a `MonorepoProject` with `turbo: true` (the default), Turborepo is automatically configured. Sub-projects created with `TypeScriptProject` automatically get Turborepo task configuration if their parent has Turborepo enabled.
|
|
439
|
+
|
|
440
|
+
The integration includes:
|
|
441
|
+
- Automatic task definitions (compile, test, package)
|
|
442
|
+
- Output directory configuration (`dist/**`, `lib/**`)
|
|
443
|
+
- Remote cache support (when configured)
|
|
444
|
+
- Build workflow integration
|
|
445
|
+
|
|
446
|
+
See the [Turbo Repo](#turbo-repo) section for more details.
|
|
447
|
+
|
|
448
|
+
## Configuration Options
|
|
449
|
+
|
|
450
|
+
### MonorepoProjectOptions
|
|
451
|
+
|
|
452
|
+
Extends `TypeScriptProjectOptions` with:
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
interface MonorepoProjectOptions {
|
|
456
|
+
name: string; // Required
|
|
457
|
+
turbo?: boolean; // Default: true
|
|
458
|
+
turboOptions?: TurboRepoOptions;
|
|
459
|
+
pnpmOptions?: {
|
|
460
|
+
version?: string;
|
|
461
|
+
pnpmWorkspaceOptions?: PnpmWorkspaceOptions;
|
|
462
|
+
};
|
|
463
|
+
// ... all TypeScriptProjectOptions
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### TypeScriptProjectOptions
|
|
468
|
+
|
|
469
|
+
Extends Projen's `TypeScriptProjectOptions` with CodeDrifters defaults. See the [TypeScriptProject](#typescriptproject) section for details.
|
|
470
|
+
|
|
471
|
+
### TurboRepoOptions
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
interface TurboRepoOptions {
|
|
475
|
+
turboVersion?: string;
|
|
476
|
+
remoteCacheOptions?: RemoteCacheOptions;
|
|
477
|
+
extends?: Array<string>;
|
|
478
|
+
globalDependencies?: Array<string>;
|
|
479
|
+
globalEnv?: Array<string>;
|
|
480
|
+
globalPassThroughEnv?: Array<string>;
|
|
481
|
+
ui?: 'tui' | 'stream';
|
|
482
|
+
envMode?: string;
|
|
483
|
+
// ... and more
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
interface RemoteCacheOptions {
|
|
487
|
+
profileName: string;
|
|
488
|
+
oidcRole: string;
|
|
489
|
+
endpointParamName: string;
|
|
490
|
+
tokenParamName: string;
|
|
491
|
+
teamName: string;
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### PnpmWorkspaceOptions
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
interface PnpmWorkspaceOptions {
|
|
499
|
+
fileName?: string; // Default: 'pnpm-workspace.yaml'
|
|
500
|
+
minimumReleaseAge?: number; // Minutes, default: ONE_DAY (1440)
|
|
501
|
+
minimumReleaseAgeExclude?: Array<string>; // Default: ['@codedrifters/*']
|
|
502
|
+
onlyBuiltDependencies?: Array<string>;
|
|
503
|
+
ignoredBuiltDependencies?: Array<string>;
|
|
504
|
+
subprojects?: Array<string>;
|
|
505
|
+
defaultCatalog?: { [key: string]: string };
|
|
506
|
+
namedCatalogs?: { [catalogName: string]: { [dependencyName: string]: string } };
|
|
507
|
+
}
|
|
508
|
+
```
|
|
120
509
|
|
|
121
510
|
## Turbo Repo
|
|
122
511
|
|
|
@@ -139,6 +528,25 @@ Turbo Repo is a build system for monorepos that:
|
|
|
139
528
|
|
|
140
529
|
**Remote Cache:** Build outputs stored in S3 (not Vercel) for team sharing
|
|
141
530
|
|
|
531
|
+
### Configuration
|
|
532
|
+
|
|
533
|
+
Turborepo is automatically enabled in `MonorepoProject` (can be disabled with `turbo: false`). Configure it using the `turboOptions`:
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
const project = new MonorepoProject({
|
|
537
|
+
name: 'my-monorepo',
|
|
538
|
+
turboOptions: {
|
|
539
|
+
remoteCacheOptions: {
|
|
540
|
+
profileName: 'my-profile',
|
|
541
|
+
oidcRole: 'arn:aws:iam::123456789012:role/TurborepoRole',
|
|
542
|
+
endpointParamName: '/TURBOREPO/ENDPOINT',
|
|
543
|
+
tokenParamName: '/TURBOREPO/TOKEN',
|
|
544
|
+
teamName: 'my-team',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
```
|
|
549
|
+
|
|
142
550
|
### Running Locally
|
|
143
551
|
|
|
144
552
|
Before using Turbo Repo locally, you need AWS credentials:
|
|
@@ -156,150 +564,170 @@ Before using Turbo Repo locally, you need AWS credentials:
|
|
|
156
564
|
- **Selective Rebuilds:** Only changed code rebuilds, not the entire monorepo
|
|
157
565
|
- **Local + CI Sharing:** Cache between your machine and GitHub Actions
|
|
158
566
|
|
|
159
|
-
##
|
|
160
|
-
|
|
161
|
-
Our projects include a GitHub Action that:
|
|
162
|
-
|
|
163
|
-
- Runs weekly (configurable)
|
|
164
|
-
- Checks for updated packages
|
|
165
|
-
- Opens a PR with updates
|
|
166
|
-
- Runs all tests automatically
|
|
567
|
+
## PNPM Workspace
|
|
167
568
|
|
|
168
|
-
|
|
569
|
+
The `MonorepoProject` automatically generates and manages `pnpm-workspace.yaml`. This file:
|
|
169
570
|
|
|
170
|
-
|
|
571
|
+
- Lists all sub-projects in the `packages` array
|
|
572
|
+
- Configures PNPM settings like `minimumReleaseAge` and `onlyBuiltDependencies`
|
|
573
|
+
- Defines dependency catalogs for version management
|
|
171
574
|
|
|
172
|
-
|
|
575
|
+
### Workspace Structure
|
|
173
576
|
|
|
174
|
-
-
|
|
175
|
-
- Format on save with Prettier
|
|
176
|
-
- Recommended extensions (can be customized)
|
|
577
|
+
The workspace file is auto-generated and lists all sub-projects:
|
|
177
578
|
|
|
178
|
-
|
|
579
|
+
```yaml
|
|
580
|
+
packages:
|
|
581
|
+
- 'packages/package-a'
|
|
582
|
+
- 'packages/package-b'
|
|
583
|
+
- 'apps/frontend'
|
|
584
|
+
```
|
|
179
585
|
|
|
180
|
-
|
|
586
|
+
Sub-projects are automatically discovered from `project.subprojects` and any additional paths specified in `pnpmWorkspaceOptions.subprojects`.
|
|
181
587
|
|
|
182
|
-
|
|
588
|
+
### Configuration
|
|
183
589
|
|
|
184
|
-
|
|
590
|
+
Configure the workspace through `pnpmOptions.pnpmWorkspaceOptions`:
|
|
185
591
|
|
|
186
592
|
```typescript
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
593
|
+
const project = new MonorepoProject({
|
|
594
|
+
name: 'my-monorepo',
|
|
595
|
+
pnpmOptions: {
|
|
596
|
+
pnpmWorkspaceOptions: {
|
|
597
|
+
minimumReleaseAge: MIMIMUM_RELEASE_AGE.ONE_DAY,
|
|
598
|
+
minimumReleaseAgeExclude: ['@codedrifters/*'],
|
|
599
|
+
onlyBuiltDependencies: ['@swc/core', 'esbuild'],
|
|
600
|
+
defaultCatalog: {
|
|
601
|
+
'react': '^18.0.0',
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
});
|
|
192
606
|
```
|
|
193
607
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
```typescript
|
|
197
|
-
// Adds Playwright testing framework
|
|
198
|
-
import { PlaywrightComponent } from './.projenrc/playwright';
|
|
608
|
+
## File Management Rules
|
|
199
609
|
|
|
200
|
-
|
|
201
|
-
```
|
|
610
|
+
### DO NOT Edit These Files Directly
|
|
202
611
|
|
|
203
|
-
|
|
612
|
+
Projen manages many files automatically. Never edit these files by hand:
|
|
204
613
|
|
|
205
|
-
-
|
|
206
|
-
-
|
|
614
|
+
- Configuration files (`.prettierrc`, `tsconfig.json`, etc.)
|
|
615
|
+
- GitHub workflows (`.github/workflows/*`)
|
|
207
616
|
- Build scripts
|
|
208
|
-
-
|
|
209
|
-
|
|
210
|
-
### Sample Files vs Config Files
|
|
211
|
-
|
|
212
|
-
**Config Files:** Deleted and regenerated on every `npx projen` run
|
|
213
|
-
|
|
214
|
-
- YAML, JSON, INI files
|
|
215
|
-
- TypeScript configs
|
|
216
|
-
- Build configurations
|
|
217
|
-
|
|
218
|
-
**Sample Files:** Generated once, never overwritten
|
|
219
|
-
|
|
220
|
-
- Starter code templates
|
|
221
|
-
- Example tests
|
|
222
|
-
- Framework setup files (e.g., Storybook's `main.ts`)
|
|
223
|
-
|
|
224
|
-
Sample files give you a starting point but won't receive updates. Modify them freely for your needs.
|
|
617
|
+
- Most files listed in `.projen/files.json`
|
|
225
618
|
|
|
226
|
-
|
|
619
|
+
### Exception: package.json
|
|
227
620
|
|
|
228
|
-
|
|
621
|
+
`package.json` is special - Projen reads, modifies, and writes it back, preserving some manual changes. However, you should still manage dependencies through Projen config, not by editing `package.json` directly.
|
|
229
622
|
|
|
230
|
-
|
|
623
|
+
### Adding Dependencies
|
|
231
624
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- 'packages/package-b'
|
|
236
|
-
- 'apps/frontend'
|
|
625
|
+
**WRONG:**
|
|
626
|
+
```bash
|
|
627
|
+
npm install some-package
|
|
237
628
|
```
|
|
238
629
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
You can:
|
|
242
|
-
|
|
243
|
-
- Open the entire monorepo (uses root `.vscode/`)
|
|
244
|
-
- Open individual sub-projects (can have their own `.vscode/`)
|
|
630
|
+
**CORRECT:** Add dependencies in your `.projenrc.ts` configuration and run `npx projen`.
|
|
245
631
|
|
|
246
|
-
|
|
632
|
+
```typescript
|
|
633
|
+
const project = new TypeScriptProject({
|
|
634
|
+
// ... other options
|
|
635
|
+
deps: ['some-package'],
|
|
636
|
+
});
|
|
637
|
+
```
|
|
247
638
|
|
|
248
639
|
## Workflow Tips
|
|
249
640
|
|
|
250
641
|
### Before Committing
|
|
251
642
|
|
|
252
|
-
Run Turbo build locally to cache everything:
|
|
643
|
+
Run Turbo build locally (from monorepo root) to cache everything:
|
|
253
644
|
|
|
254
645
|
```bash
|
|
255
646
|
# This caches outputs that GitHub Actions can reuse
|
|
256
|
-
|
|
647
|
+
pnpm build:all
|
|
257
648
|
```
|
|
258
649
|
|
|
259
650
|
Then commit and push. Your GitHub build will be much faster.
|
|
260
651
|
|
|
261
652
|
### Adding New Packages
|
|
262
653
|
|
|
263
|
-
1.
|
|
264
|
-
2.
|
|
265
|
-
3.
|
|
266
|
-
4.
|
|
654
|
+
1. Create a new configuration file in `projenrc/` (e.g., `projenrc/new-package.ts`)
|
|
655
|
+
2. Export a function that creates a `TypeScriptProject` with the parent as a parameter
|
|
656
|
+
3. Import and call it in your main projenrc file
|
|
657
|
+
4. Run `npx projen` to regenerate configs
|
|
658
|
+
5. Commit the changes
|
|
659
|
+
|
|
660
|
+
Example:
|
|
661
|
+
|
|
662
|
+
```typescript
|
|
663
|
+
// projenrc/new-package.ts
|
|
664
|
+
import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
|
|
665
|
+
|
|
666
|
+
export const configureNewPackage = (parent: MonorepoProject) => {
|
|
667
|
+
return new TypeScriptProject({
|
|
668
|
+
name: 'new-package',
|
|
669
|
+
packageName: '@myorg/new-package',
|
|
670
|
+
outdir: 'packages/new-package',
|
|
671
|
+
parent,
|
|
672
|
+
deps: ['dependency'],
|
|
673
|
+
});
|
|
674
|
+
};
|
|
675
|
+
```
|
|
267
676
|
|
|
268
677
|
### Updating Configulator
|
|
269
678
|
|
|
270
679
|
To receive updates from Configulator in your project:
|
|
271
680
|
|
|
272
|
-
1. Update the version in
|
|
681
|
+
1. Update the version in your projenrc definition file
|
|
273
682
|
2. Run `npx projen`
|
|
274
683
|
3. Review and test changes
|
|
275
684
|
4. Commit
|
|
276
685
|
|
|
277
|
-
##
|
|
686
|
+
## API Reference
|
|
278
687
|
|
|
279
|
-
###
|
|
688
|
+
### MonorepoProject
|
|
689
|
+
|
|
690
|
+
**Constructor:**
|
|
691
|
+
```typescript
|
|
692
|
+
new MonorepoProject(options: MonorepoProjectOptions)
|
|
693
|
+
```
|
|
280
694
|
|
|
281
|
-
|
|
695
|
+
**Key Properties:**
|
|
696
|
+
- `pnpmVersion: string` - The PNPM version used by the monorepo
|
|
282
697
|
|
|
698
|
+
**Key Methods:**
|
|
699
|
+
- Inherits all methods from `TypeScriptAppProject`
|
|
700
|
+
|
|
701
|
+
### TypeScriptProject
|
|
702
|
+
|
|
703
|
+
**Constructor:**
|
|
283
704
|
```typescript
|
|
284
|
-
|
|
285
|
-
turbo: '1.10.0',
|
|
286
|
-
pnpm: '8.6.0',
|
|
287
|
-
node: '18.x'
|
|
288
|
-
};
|
|
705
|
+
new TypeScriptProject(options: TypeScriptProjectOptions)
|
|
289
706
|
```
|
|
290
707
|
|
|
291
|
-
|
|
708
|
+
**Key Methods:**
|
|
709
|
+
- `addDeps(...deps: string[])` - Add runtime dependencies
|
|
710
|
+
- `addDevDeps(...deps: string[])` - Add dev dependencies
|
|
711
|
+
- `addPeerDeps(...deps: string[])` - Add peer dependencies
|
|
712
|
+
- Inherits all methods from Projen's `TypeScriptProject`
|
|
292
713
|
|
|
293
|
-
###
|
|
714
|
+
### PnpmWorkspace
|
|
294
715
|
|
|
295
|
-
|
|
716
|
+
**Static Method:**
|
|
717
|
+
```typescript
|
|
718
|
+
PnpmWorkspace.of(project: Project): PnpmWorkspace | undefined
|
|
719
|
+
```
|
|
296
720
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
721
|
+
Returns the PnpmWorkspace component from a project if it exists.
|
|
722
|
+
|
|
723
|
+
### TurboRepo
|
|
724
|
+
|
|
725
|
+
**Static Method:**
|
|
726
|
+
```typescript
|
|
727
|
+
TurboRepo.of(project: Project): TurboRepo | undefined
|
|
300
728
|
```
|
|
301
729
|
|
|
302
|
-
|
|
730
|
+
Returns the TurboRepo component from a project if it exists.
|
|
303
731
|
|
|
304
732
|
## Troubleshooting
|
|
305
733
|
|
|
@@ -320,36 +748,19 @@ Check that you haven't manually edited generated files. If you have, run `npx pr
|
|
|
320
748
|
|
|
321
749
|
Don't mix `npm install` with Projen. Always add dependencies through configuration.
|
|
322
750
|
|
|
323
|
-
|
|
751
|
+
**Sub-project not appearing in workspace**
|
|
324
752
|
|
|
325
|
-
-
|
|
326
|
-
-
|
|
327
|
-
-
|
|
328
|
-
- Set up AWS profiles for Turbo Repo remote caching
|
|
753
|
+
- Ensure the sub-project has `parent` set to the MonorepoProject
|
|
754
|
+
- Ensure `outdir` is set correctly
|
|
755
|
+
- Run `npx projen` to regenerate the workspace file
|
|
329
756
|
|
|
330
757
|
## Additional Resources
|
|
331
758
|
|
|
332
759
|
- **Projen Documentation:** https://projen.io
|
|
333
760
|
- **Turbo Repo Docs:** https://turbo.build/repo/docs
|
|
334
|
-
- **
|
|
761
|
+
- **PNPM Workspaces:** https://pnpm.io/workspaces
|
|
762
|
+
- **Code Drifters Configulator:** https://www.npmjs.com/package/@codedrifters/packages
|
|
335
763
|
|
|
336
764
|
---
|
|
337
765
|
|
|
338
766
|
**Remember:** The goal is consistency and automation. Let the tools manage the boilerplate so you can focus on building features.
|
|
339
|
-
|
|
340
|
-
# **ARCHIVE FROM INITIAL SETUP**
|
|
341
|
-
## Configulator
|
|
342
|
-
|
|
343
|
-
A library of [Projen](https://projen.io/) components used by CodeDrifters to manage repository configuration across various projects.
|
|
344
|
-
|
|
345
|
-
## Usage
|
|
346
|
-
|
|
347
|
-
To init a monorepo you can use:
|
|
348
|
-
|
|
349
|
-
`npx projen new --from @codedrifters/configulator monorepo`
|
|
350
|
-
|
|
351
|
-
For a specific version, use:
|
|
352
|
-
|
|
353
|
-
`npx projen new --from @codedrifters/configulator@0.0.15 monorepo`
|
|
354
|
-
|
|
355
|
-
These docs are a work in progress and very light currently.
|