quick-scaffolds-cli 1.2.5 → 1.3.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/README.md +88 -48
- package/bin/cli.js +77 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# quick-scaffolds-cli
|
|
2
2
|
|
|
3
|
-
A lightweight interactive CLI for scaffolding starter web projects
|
|
3
|
+
A lightweight, interactive CLI for scaffolding starter web projects in seconds.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
quick-scaffolds-cli
|
|
7
|
+
quick-scaffolds-cli is a command-line tool that generates ready-to-use web project starters with zero configuration. Answer a few simple prompts and get a fully structured project—choose between static HTML/CSS/JS or a modern React + Vite setup.
|
|
8
8
|
|
|
9
|
-
Current release
|
|
9
|
+
**Current release:** v1.3.0 | **License:** MIT
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ Install once and use the command anywhere:
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npm install -g quick-scaffolds-cli
|
|
19
|
-
ct-pro
|
|
19
|
+
ct-pro
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
### Use with npx
|
|
@@ -24,43 +24,37 @@ ct-pro my-awesome-app
|
|
|
24
24
|
Run without installing globally:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
npx quick-scaffolds-cli
|
|
27
|
+
npx quick-scaffolds-cli
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
32
|
-
Run the CLI
|
|
32
|
+
Run the CLI and answer the prompts:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
ct-pro
|
|
36
|
-
?
|
|
35
|
+
ct-pro
|
|
36
|
+
? What is your project name will be ? (Type "." to use the current directory) my-awesome-app
|
|
37
37
|
? What do you want to build?
|
|
38
|
-
Static HTML/CSS/JS
|
|
39
|
-
|
|
38
|
+
❯ Static HTML/CSS/JS
|
|
39
|
+
React starter
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
Prompt
|
|
42
|
+
### Prompt Details
|
|
43
43
|
|
|
44
|
-
1.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
2. Project type:
|
|
48
|
-
- Static HTML/CSS/JS
|
|
49
|
-
- React starter
|
|
44
|
+
**1. Project Name**
|
|
45
|
+
- Enter a new folder name to create a new directory (default: `my-new-project`)
|
|
46
|
+
- Enter `.` to scaffold directly in the current directory
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
? What is your project name? my-updated-app
|
|
55
|
-
```
|
|
48
|
+
**2. Project Type**
|
|
49
|
+
- **Static HTML/CSS/JS:** A simple, lightweight static site starter—perfect for learning or quick prototypes
|
|
50
|
+
- **React starter:** A modern React app with Vite, ESM modules, and optional React Router setup for navigation
|
|
56
51
|
|
|
57
52
|
## Templates
|
|
58
53
|
|
|
59
54
|
### 1. Static HTML/CSS/JS
|
|
55
|
+
A simple, minimal starter template for static web projects.
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Generated structure:
|
|
57
|
+
**Generated structure:**
|
|
64
58
|
|
|
65
59
|
```text
|
|
66
60
|
my-awesome-app/
|
|
@@ -71,17 +65,26 @@ my-awesome-app/
|
|
|
71
65
|
└── app.js
|
|
72
66
|
```
|
|
73
67
|
|
|
74
|
-
|
|
68
|
+
**Next steps:**
|
|
69
|
+
```bash
|
|
70
|
+
cd my-awesome-app
|
|
71
|
+
# Open index.html in your browser
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
### 2. React Starter (Vite + Modern ESM)
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
A modern React starter with Vite, automatic dependency installation, and optional React Router setup.
|
|
79
|
+
|
|
80
|
+
**Generated structure:**
|
|
79
81
|
|
|
80
82
|
```text
|
|
81
83
|
my-awesome-app/
|
|
82
84
|
├── .gitignore
|
|
83
85
|
├── index.html
|
|
84
86
|
├── package.json
|
|
87
|
+
├── vite.config.js
|
|
85
88
|
├── public/
|
|
86
89
|
│ └── index.css
|
|
87
90
|
└── src/
|
|
@@ -91,43 +94,80 @@ my-awesome-app/
|
|
|
91
94
|
└── main.jsx
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
**Interactive setup:**
|
|
98
|
+
- 📦 Automatically installs npm dependencies after scaffolding
|
|
99
|
+
- 🛣️ Prompts to install **React Router** for navigation (optional)
|
|
100
|
+
✨ **Interactive CLI** — User-friendly prompts powered by [@inquirer/prompts](https://www.npmjs.com/package/@inquirer/prompts)
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
⚡ **Zero Configuration** — Choose a template and get a working project instantly
|
|
103
|
+
|
|
104
|
+
🎨 **Two Templates:**
|
|
105
|
+
- Static HTML/CSS/JS for simple projects
|
|
106
|
+
- React + Vite with modern ESM module support
|
|
107
|
+
|
|
108
|
+
🛣️ **React Router Setup** — Optional routing configuration for multi-page React apps
|
|
109
|
+
|
|
110
|
+
📦 **Automatic Dependencies** — npm install runs automatically for React projects
|
|
111
|
+
|
|
112
|
+
🎯 **Current Directory Support** — Use `.` to scaffold in your existing folder
|
|
113
|
+
|
|
114
|
+
🚀 **Simple Command Interface** — Just run `ct-pro` from anywhere
|
|
99
115
|
```
|
|
100
116
|
|
|
117
|
+
The generated app includes a counter button in `App.jsx` so you can immediately see React state updates in action
|
|
101
118
|
The generated app includes a counter button and last-click timestamp in `App.jsx` so you can quickly confirm rendering and state updates.
|
|
102
119
|
|
|
103
120
|
## Features
|
|
104
121
|
|
|
105
|
-
|
|
106
|
-
- Fast project scaffolding from local templates
|
|
107
|
-
- Two starter options: static web or React + Vite
|
|
108
|
-
- Automatic dependency installation for React template
|
|
109
|
-
- Simple command interface via ct-pro
|
|
110
|
-
|
|
111
|
-
## Troubleshooting
|
|
122
|
+
### React Project is Blank
|
|
112
123
|
|
|
113
|
-
|
|
124
|
+
Ensure you're running the development server:
|
|
114
125
|
|
|
115
126
|
```bash
|
|
116
127
|
cd my-awesome-app
|
|
117
128
|
npm run dev
|
|
118
129
|
```
|
|
119
130
|
|
|
120
|
-
|
|
121
|
-
- `index.html` loads `./src/main.jsx`
|
|
122
|
-
- `main.jsx` renders `App.jsx`
|
|
131
|
+
Then open http://localhost:5173 in your browser.
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
### React Entry Point
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
The React app boots in this order:
|
|
136
|
+
1. `index.html` loads your app into the root div
|
|
137
|
+
2. `src/main.jsx` renders the React app
|
|
138
|
+
3. `App.jsx` is the root React component
|
|
139
|
+
|
|
140
|
+
### Dependencies Installation Failed
|
|
141
|
+
The quick-scaffolds-cli repository is organized as follows:
|
|
129
142
|
|
|
130
|
-
|
|
143
|
+
```text
|
|
144
|
+
quick-scaffolds-cli/
|
|
145
|
+
├── LICENSE
|
|
146
|
+
├── README.md
|
|
147
|
+
├── package.json
|
|
148
|
+
├── bin/
|
|
149
|
+
│ └── cli.js # Main CLI entry point
|
|
150
|
+
├── templates/
|
|
151
|
+
│ ├── html-template/ # Static web starter
|
|
152
|
+
│ │ ├── index.html
|
|
153
|
+
│ │ ├── css/
|
|
154
|
+
│ │ │ └── style.css
|
|
155
|
+
│ │ └── js/
|
|
156
|
+
│ │ └── app.js
|
|
157
|
+
│ └── react-template/ # React + Vite starter
|
|
158
|
+
│ ├── .gitignore
|
|
159
|
+
│ ├── index.html
|
|
160
|
+
│ ├── package.json
|
|
161
|
+
│ ├── vite.config.js
|
|
162
|
+
│ ├── public/
|
|
163
|
+
│ │ └── index.css
|
|
164
|
+
│ └── src/
|
|
165
|
+
│ ├── App.css
|
|
166
|
+
│ ├── App.jsx
|
|
167
|
+
│ ├── index.css
|
|
168
|
+
│ ├── main.jsx
|
|
169
|
+
│ └── pages/ # (created if React Router is selected)
|
|
170
|
+
│ └── Home.jsx
|
|
131
171
|
|
|
132
172
|
```text
|
|
133
173
|
quick-scaffolds-cli/
|
package/bin/cli.js
CHANGED
|
@@ -9,24 +9,14 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
10
|
|
|
11
11
|
async function main() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
name = await input(
|
|
21
|
-
{
|
|
22
|
-
name: 'projectName',
|
|
23
|
-
message: 'What is your project name?',
|
|
24
|
-
type: 'input',
|
|
25
|
-
default: 'my-new-project'
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
12
|
+
const name = await input(
|
|
13
|
+
{
|
|
14
|
+
name: 'projectName',
|
|
15
|
+
message: 'What is your project name will be ? (Type "." to use the current directory)',
|
|
16
|
+
type: 'input',
|
|
17
|
+
default: 'my-new-project'
|
|
18
|
+
}
|
|
19
|
+
);
|
|
30
20
|
const projectType = await select({
|
|
31
21
|
message: 'What do you want to build?',
|
|
32
22
|
type: "list",
|
|
@@ -47,12 +37,15 @@ async function main() {
|
|
|
47
37
|
}
|
|
48
38
|
try {
|
|
49
39
|
const projectName = name;
|
|
50
|
-
const targetPath = path.join(process.cwd(), projectName);
|
|
40
|
+
const targetPath = projectName === '.' ? process.cwd() : path.join(process.cwd(), projectName);
|
|
51
41
|
|
|
52
42
|
const templatePath = path.join(__dirname, '../templates', templateFolder);
|
|
53
|
-
|
|
43
|
+
if (projectName !== '.') {
|
|
44
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
45
|
+
}
|
|
54
46
|
await fs.cp(templatePath, targetPath, { recursive: true });
|
|
55
|
-
|
|
47
|
+
const displayName = projectName === '.' ? path.basename(process.cwd()) : projectName;
|
|
48
|
+
console.log(`\nSuccessfully scaffolded the HTMl project - ${displayName}\n`)
|
|
56
49
|
|
|
57
50
|
} catch (err) {
|
|
58
51
|
console.error(`Error - ${err.message}`)
|
|
@@ -61,9 +54,14 @@ async function main() {
|
|
|
61
54
|
|
|
62
55
|
async function reactApp(projectName, templateFolder) {
|
|
63
56
|
try {
|
|
64
|
-
const
|
|
57
|
+
const isCurrentDirectory = projectName === '.';
|
|
58
|
+
const targetPath = isCurrentDirectory ? process.cwd() : path.join(process.cwd(), projectName);
|
|
59
|
+
const displayName = isCurrentDirectory ? path.basename(process.cwd()) : projectName;
|
|
60
|
+
|
|
65
61
|
const templatePath = path.join(__dirname, '../templates', templateFolder);
|
|
66
|
-
|
|
62
|
+
if (!isCurrentDirectory) {
|
|
63
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
64
|
+
}
|
|
67
65
|
await fs.cp(templatePath, targetPath, { recursive: true })
|
|
68
66
|
|
|
69
67
|
const filesToUpdate = [
|
|
@@ -73,15 +71,16 @@ async function reactApp(projectName, templateFolder) {
|
|
|
73
71
|
for (const filePath of filesToUpdate) {
|
|
74
72
|
try {
|
|
75
73
|
const content = await fs.readFile(filePath, 'utf-8');
|
|
76
|
-
const updateContent = content.replaceAll('{{PROJECT_NAME}}',
|
|
74
|
+
const updateContent = content.replaceAll('{{PROJECT_NAME}}', displayName);
|
|
77
75
|
await fs.writeFile(filePath, updateContent);
|
|
78
76
|
} catch (err) {
|
|
77
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
79
78
|
console.error(err);
|
|
80
79
|
console.error(`File path ${path.basename(filePath)} not found`);
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
console.log(`Successfully scaffolded the React starter project - ${
|
|
83
|
+
console.log(`Successfully scaffolded the React starter project - ${displayName}\n`)
|
|
85
84
|
console.log('📦 Installing dependencies... This may take a minute.\n');
|
|
86
85
|
try {
|
|
87
86
|
execSync('npm install', {
|
|
@@ -89,6 +88,59 @@ async function reactApp(projectName, templateFolder) {
|
|
|
89
88
|
stdio: 'inherit'
|
|
90
89
|
});
|
|
91
90
|
console.log('✅ Dependencies installed successfully!\n');
|
|
91
|
+
|
|
92
|
+
const addRouterQuestion = await confirm({
|
|
93
|
+
message: 'Whould you like to setup React Router for navigation ?',
|
|
94
|
+
default: true
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
if (addRouterQuestion) {
|
|
98
|
+
console.log('Adding React Router...📦')
|
|
99
|
+
execSync('npm install react-router-dom', {
|
|
100
|
+
cwd: targetPath,
|
|
101
|
+
stdio: 'inherit'
|
|
102
|
+
});
|
|
103
|
+
const routerAppCode = `
|
|
104
|
+
|
|
105
|
+
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
|
106
|
+
import Home from './pages/Home';
|
|
107
|
+
import React from 'react';
|
|
108
|
+
|
|
109
|
+
function App() {
|
|
110
|
+
return (
|
|
111
|
+
<Router>
|
|
112
|
+
<Routes>
|
|
113
|
+
<Route path="/" element={<Home />} />
|
|
114
|
+
</Routes>
|
|
115
|
+
</Router>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export default App;
|
|
120
|
+
|
|
121
|
+
`;
|
|
122
|
+
const appJsxPath = path.join(targetPath, 'src', 'App.jsx');
|
|
123
|
+
await fs.writeFile(appJsxPath, routerAppCode);
|
|
124
|
+
const pageDirPath = path.join(targetPath, 'src', 'pages');
|
|
125
|
+
await fs.mkdir(pageDirPath, { recursive: true});
|
|
126
|
+
const homeComponentCode =`
|
|
127
|
+
|
|
128
|
+
import React from 'react';
|
|
129
|
+
|
|
130
|
+
export default function Home() {
|
|
131
|
+
return (
|
|
132
|
+
<div>
|
|
133
|
+
<h1>Welcome Home</h1>
|
|
134
|
+
<p>Your React Router is up and running!</p>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
const homeComponentPath = path.join(pageDirPath, 'Home.jsx');
|
|
140
|
+
await fs.writeFile(homeComponentPath, homeComponentCode);
|
|
141
|
+
console.log('✅ Successfully added React Router');
|
|
142
|
+
|
|
143
|
+
}
|
|
92
144
|
} catch (err) {
|
|
93
145
|
console.error(err);
|
|
94
146
|
console.log('⚠️ Could not install dependencies automatically.\n');
|