Skip to content

Commit aaf8f0a

Browse files
committed
Split into two scripts
1 parent 65191e3 commit aaf8f0a

6 files changed

Lines changed: 99 additions & 82 deletions

File tree

packages/create-vite-app/PLAN.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Implementation Plan: @fastify/create-vite-app CLI
22

33
## Overview
4+
45
Build a CLI scaffolding tool that copies the `examples/react-vanilla-spa/` template and resolves pnpm catalog versions at build time.
56

67
## Requirements Summary
8+
79
- **Template source**: `examples/react-vanilla-spa/` (bundled at build time)
810
- **Prompts**: Project name only (using @clack/prompts)
911
- **Versions**: Baked in at build time from `pnpm-workspace.yaml`
@@ -15,22 +17,27 @@ Build a CLI scaffolding tool that copies the `examples/react-vanilla-spa/` templ
1517
## Implementation (Completed)
1618

1719
### Step 1: Add dependencies
20+
1821
**File**: `packages/create-vite-app/package.json`
1922

2023
Added:
24+
2125
- `@clack/prompts` ^0.11.0 - interactive CLI prompts
2226
- `yaml` ^2.8.2 (devDependency) - parse pnpm-workspace.yaml at build time
2327

2428
### Step 2: Create build script
29+
2530
**File**: `packages/create-vite-app/scripts/generate-versions.ts`
2631

2732
This script:
33+
2834
1. Reads `pnpm-workspace.yaml` for catalog versions
2935
2. Reads `packages/fastify-vite/package.json` for @fastify/vite version
3036
3. Writes `src/versions.json` with resolved versions
3137
4. Copies template files from `examples/react-vanilla-spa` to `templates/react-spa`
3238

3339
### Step 3: Update build script in package.json
40+
3441
**File**: `packages/create-vite-app/package.json`
3542

3643
```json
@@ -40,34 +47,38 @@ This script:
4047
(Uses Node 22.18+ native TypeScript support - no tsx needed)
4148

4249
### Step 4: Rewrite src/index.ts
50+
4351
**File**: `packages/create-vite-app/src/index.ts`
4452

4553
Features:
54+
4655
- Interactive project name prompt using @clack/prompts
4756
- Copies template files from bundled `templates/react-spa`
4857
- Transforms package.json (resolves versions, updates name)
4958
- Auto-detects package manager and installs dependencies
5059
- Shows spinner during operations
5160

5261
### Step 5: Create .gitignore
62+
5363
**File**: `packages/create-vite-app/.gitignore`
5464

5565
Ignores build-time generated files:
66+
5667
- `src/versions.json`
5768
- `templates/`
5869

5970
---
6071

6172
## Files Modified/Created
6273

63-
| File | Action |
64-
|------|--------|
65-
| `packages/create-vite-app/package.json` | Modified - added deps, updated build script |
66-
| `packages/create-vite-app/scripts/generate-versions.ts` | Created |
67-
| `packages/create-vite-app/src/versions.json` | Generated (gitignored) |
68-
| `packages/create-vite-app/src/index.ts` | Rewritten |
69-
| `packages/create-vite-app/.gitignore` | Created |
70-
| `packages/create-vite-app/templates/` | Generated (gitignored) |
74+
| File | Action |
75+
| ------------------------------------------------------- | ------------------------------------------- |
76+
| `packages/create-vite-app/package.json` | Modified - added deps, updated build script |
77+
| `packages/create-vite-app/scripts/generate-versions.ts` | Created |
78+
| `packages/create-vite-app/src/versions.json` | Generated (gitignored) |
79+
| `packages/create-vite-app/src/index.ts` | Rewritten |
80+
| `packages/create-vite-app/.gitignore` | Created |
81+
| `packages/create-vite-app/templates/` | Generated (gitignored) |
7182

7283
---
7384

@@ -89,11 +100,11 @@ project-name/
89100

90101
## Version Mapping
91102

92-
| Source Reference | Package | Resolved |
93-
|-----------------|---------|----------|
94-
| `workspace:^` | @fastify/vite | ^8.2.3 |
95-
| `catalog:` | fastify | ^5.6.2 |
96-
| `catalog:` | vite | ^7.3.0 |
97-
| `catalog:react` | react | ^19.2.3 |
98-
| `catalog:react` | react-dom | ^19.2.3 |
99-
| `catalog:react` | @vitejs/plugin-react | ^5.1.2 |
103+
| Source Reference | Package | Resolved |
104+
| ---------------- | -------------------- | -------- |
105+
| `workspace:^` | @fastify/vite | ^8.2.3 |
106+
| `catalog:` | fastify | ^5.6.2 |
107+
| `catalog:` | vite | ^7.3.0 |
108+
| `catalog:react` | react | ^19.2.3 |
109+
| `catalog:react` | react-dom | ^19.2.3 |
110+
| `catalog:react` | @vitejs/plugin-react | ^5.1.2 |

packages/create-vite-app/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ The official scaffolding tool for **Fastify + Vite** applications.
77
You do not need to install this package globally. You can run it directly using your package manager of choice.
88

99
### npm
10+
1011
```bash
1112
npm create @fastify/vite-app@latest
1213
# or with a specific project name
1314
npm create @fastify/vite-app@latest my-app
1415
```
1516

1617
### pnpm
18+
1719
```bash
1820
pnpm create @fastify/vite-app@latest
1921
```
2022

2123
### yarn
24+
2225
```bash
2326
yarn create @fastify/vite-app
2427
```

packages/create-vite-app/package.json

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@
22
"name": "@fastify/create-vite-app",
33
"version": "0.0.0",
44
"description": "Scaffolding tool for Fastify + Vite applications",
5-
"type": "module",
5+
"keywords": [
6+
"cli",
7+
"create-fastify-app",
8+
"fastify",
9+
"scaffold",
10+
"vite"
11+
],
12+
"license": "MIT",
13+
"author": "Fastify Team",
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/fastify/fastify-vite.git",
17+
"directory": "packages/create-vite-app"
18+
},
619
"bin": {
720
"create-vite-app": "./dist/index.js",
821
"fastify-create-vite-app": "./dist/index.js"
@@ -11,38 +24,26 @@
1124
"dist",
1225
"templates"
1326
],
14-
"scripts": {
15-
"dev": "node src/index.ts",
16-
"build": "node scripts/generate-versions.ts && tsc",
17-
"prepublishOnly": "pnpm build",
18-
"test": "node --test"
19-
},
27+
"type": "module",
2028
"publishConfig": {
2129
"access": "public"
2230
},
23-
"repository": {
24-
"type": "git",
25-
"url": "git+https://github.com/fastify/fastify-vite.git",
26-
"directory": "packages/create-vite-app"
27-
},
28-
"keywords": [
29-
"fastify",
30-
"vite",
31-
"create-fastify-app",
32-
"scaffold",
33-
"cli"
34-
],
35-
"author": "Fastify Team",
36-
"license": "MIT",
37-
"engines": {
38-
"node": ">=22.18.0"
31+
"scripts": {
32+
"build": "pnpm generate-versions && pnpm copy-examples && tsc",
33+
"copy-examples": "node scripts/copy-examples.ts",
34+
"generate-versions": "node scripts/generate-versions.ts",
35+
"prepublishOnly": "pnpm build",
36+
"test": "node --test"
3937
},
4038
"dependencies": {
4139
"@clack/prompts": "^0.11.0"
4240
},
4341
"devDependencies": {
44-
"typescript": "catalog:",
4542
"@types/node": "catalog:",
43+
"typescript": "catalog:",
4644
"yaml": "^2.8.2"
45+
},
46+
"engines": {
47+
"node": ">=22.18.0"
4748
}
4849
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs'
2+
import { join } from 'node:path'
3+
4+
const rootDir = join(import.meta.dirname, '..', '..', '..')
5+
const pkgDir = join(import.meta.dirname, '..')
6+
7+
const SKIP_PATTERNS = ['node_modules', 'dist', '.test.js', '.test.ts']
8+
9+
function shouldSkip(name: string): boolean {
10+
return SKIP_PATTERNS.some((pattern) => name.includes(pattern))
11+
}
12+
13+
function copyTemplate(src: string, dest: string): void {
14+
const entries = readdirSync(src, { withFileTypes: true })
15+
16+
for (const entry of entries) {
17+
if (shouldSkip(entry.name)) continue
18+
19+
const srcPath = join(src, entry.name)
20+
const destPath = join(dest, entry.name)
21+
22+
if (entry.isDirectory()) {
23+
mkdirSync(destPath, { recursive: true })
24+
copyTemplate(srcPath, destPath)
25+
} else {
26+
cpSync(srcPath, destPath)
27+
}
28+
}
29+
}
30+
31+
const templateSrc = join(rootDir, 'examples', 'react-vanilla-spa')
32+
const templateDest = join(pkgDir, 'templates', 'react-spa')
33+
34+
// Clean and recreate templates directory
35+
if (existsSync(join(pkgDir, 'templates'))) {
36+
rmSync(join(pkgDir, 'templates'), { recursive: true })
37+
}
38+
mkdirSync(templateDest, { recursive: true })
39+
40+
copyTemplate(templateSrc, templateDest)
41+
console.log('Copied template files to templates/react-spa')
Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'
1+
import { readFileSync, writeFileSync } from 'node:fs'
22
import { join } from 'node:path'
33
import { parse } from 'yaml'
44

@@ -14,7 +14,7 @@ const workspace = parse(workspaceYaml) as {
1414

1515
// Read @fastify/vite version from its package.json
1616
const fastifyVitePkg = JSON.parse(
17-
readFileSync(join(rootDir, 'packages', 'fastify-vite', 'package.json'), 'utf-8')
17+
readFileSync(join(rootDir, 'packages', 'fastify-vite', 'package.json'), 'utf-8'),
1818
)
1919

2020
// Build the versions object
@@ -31,40 +31,3 @@ const versions: Record<string, string> = {
3131
const versionsPath = join(pkgDir, 'src', 'versions.json')
3232
writeFileSync(versionsPath, JSON.stringify(versions, null, 2) + '\n')
3333
console.log('Generated src/versions.json with versions:', versions)
34-
35-
// Copy template files from examples/react-vanilla-spa to templates/react-spa
36-
const SKIP_PATTERNS = ['node_modules', 'dist', '.test.js', '.test.ts']
37-
38-
function shouldSkip(name: string): boolean {
39-
return SKIP_PATTERNS.some((pattern) => name.includes(pattern))
40-
}
41-
42-
function copyTemplate(src: string, dest: string): void {
43-
const entries = readdirSync(src, { withFileTypes: true })
44-
45-
for (const entry of entries) {
46-
if (shouldSkip(entry.name)) continue
47-
48-
const srcPath = join(src, entry.name)
49-
const destPath = join(dest, entry.name)
50-
51-
if (entry.isDirectory()) {
52-
mkdirSync(destPath, { recursive: true })
53-
copyTemplate(srcPath, destPath)
54-
} else {
55-
cpSync(srcPath, destPath)
56-
}
57-
}
58-
}
59-
60-
const templateSrc = join(rootDir, 'examples', 'react-vanilla-spa')
61-
const templateDest = join(pkgDir, 'templates', 'react-spa')
62-
63-
// Clean and recreate templates directory
64-
if (existsSync(join(pkgDir, 'templates'))) {
65-
rmSync(join(pkgDir, 'templates'), { recursive: true })
66-
}
67-
mkdirSync(templateDest, { recursive: true })
68-
69-
copyTemplate(templateSrc, templateDest)
70-
console.log('Copied template files to templates/react-spa')

packages/create-vite-app/tsconfig.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,5 @@
88
"allowImportingTsExtensions": true,
99
"noEmit": false
1010
},
11-
"include": [
12-
"src/**/*"
13-
]
11+
"include": ["src/**/*"]
1412
}

0 commit comments

Comments
 (0)