react-tailwind-ak-kit 1.0.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/README.md +124 -0
- package/index.js +408 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
π React Tailwind AK Kit
|
|
2
|
+
|
|
3
|
+
β‘ A production-ready React + Tailwind CLI starter
|
|
4
|
+
Build scalable, modern React applications in seconds β not hours.
|
|
5
|
+
|
|
6
|
+
β¨ Why React Tailwind AK Kit?
|
|
7
|
+
|
|
8
|
+
Setting up a new React project usually means:
|
|
9
|
+
Installing dependencies
|
|
10
|
+
Configuring Tailwind
|
|
11
|
+
Setting up routing
|
|
12
|
+
Creating folder structure
|
|
13
|
+
Preparing API layer
|
|
14
|
+
Cleaning boilerplate
|
|
15
|
+
|
|
16
|
+
All this takes time β and itβs mostly repetitive work.
|
|
17
|
+
React Tailwind AK Kit eliminates that setup friction and gives you a clean, scalable architecture instantly, so you can focus on building real features instead of configuring tools.
|
|
18
|
+
|
|
19
|
+
π― Built For
|
|
20
|
+
|
|
21
|
+
π¨βπ» Frontend Developers who want structured projects
|
|
22
|
+
|
|
23
|
+
π Startup MVP builders who need rapid setup
|
|
24
|
+
|
|
25
|
+
π§ Hackathon teams who need speed
|
|
26
|
+
|
|
27
|
+
π¦ Teams who want standardized boilerplate
|
|
28
|
+
|
|
29
|
+
π― Developers building portfolio-ready production apps
|
|
30
|
+
|
|
31
|
+
β‘ Features
|
|
32
|
+
|
|
33
|
+
β‘ Vite β Lightning-fast development and build tool
|
|
34
|
+
|
|
35
|
+
π¨ Tailwind CSS β Pre-configured modern styling setup
|
|
36
|
+
|
|
37
|
+
π£οΈ React Router β Ready-to-use routing system
|
|
38
|
+
|
|
39
|
+
π‘ Axios β Structured API service layer
|
|
40
|
+
|
|
41
|
+
π Clean Architecture β Organized, scalable folder structure
|
|
42
|
+
|
|
43
|
+
βοΈ Interactive Setup Options
|
|
44
|
+
|
|
45
|
+
TypeScript (optional)
|
|
46
|
+
Redux Toolkit (optional)
|
|
47
|
+
Authentication starter structure
|
|
48
|
+
ShadCN utility support
|
|
49
|
+
Tailwind v3 (stable) or v4 (latest)
|
|
50
|
+
|
|
51
|
+
π Quick Start (Step-by-Step)
|
|
52
|
+
|
|
53
|
+
1οΈβ£ Create a New Project
|
|
54
|
+
|
|
55
|
+
Run the CLI:
|
|
56
|
+
npx react-tailwind-ak-kit my-app
|
|
57
|
+
|
|
58
|
+
2οΈβ£ Choose Your Setup Options
|
|
59
|
+
|
|
60
|
+
The CLI will ask you interactive questions like:
|
|
61
|
+
Do you want TypeScript?
|
|
62
|
+
Do you want Redux Toolkit?
|
|
63
|
+
Do you want Authentication starter?
|
|
64
|
+
Choose Tailwind version (v3 or v4)
|
|
65
|
+
Select based on your project needs.
|
|
66
|
+
|
|
67
|
+
3οΈβ£ Install Dependencies
|
|
68
|
+
|
|
69
|
+
After project generation:
|
|
70
|
+
cd my-app
|
|
71
|
+
npm install
|
|
72
|
+
|
|
73
|
+
4οΈβ£ Start Development Server
|
|
74
|
+
npm run dev
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
Your application will run at:
|
|
78
|
+
http://localhost:5173
|
|
79
|
+
|
|
80
|
+
π Generated Project Structure
|
|
81
|
+
The CLI creates a scalable and industry-standard folder architecture:
|
|
82
|
+
|
|
83
|
+
my-app/
|
|
84
|
+
βββ public/
|
|
85
|
+
βββ src/
|
|
86
|
+
β βββ assets/ β Images, fonts, static files
|
|
87
|
+
β βββ components/ β Reusable UI components
|
|
88
|
+
β β βββ ui/
|
|
89
|
+
β β βββ layout/
|
|
90
|
+
β βββ pages/ β Route-level pages
|
|
91
|
+
β βββ hooks/ β Custom React hooks
|
|
92
|
+
β βββ services/ β API calls & business logic
|
|
93
|
+
β βββ context/ β Global state management
|
|
94
|
+
β βββ routes/ β Route configuration
|
|
95
|
+
β βββ utils/ β Helper functions
|
|
96
|
+
β βββ App.jsx
|
|
97
|
+
β βββ main.jsx
|
|
98
|
+
βββ .env
|
|
99
|
+
βββ tailwind.config.js
|
|
100
|
+
βββ postcss.config.js
|
|
101
|
+
βββ package.json
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
This structure is designed for:
|
|
105
|
+
Large-scale applications
|
|
106
|
+
Maintainability
|
|
107
|
+
Clear separation of concerns
|
|
108
|
+
Clean and readable codebase
|
|
109
|
+
|
|
110
|
+
π Tech Stack
|
|
111
|
+
React 19 β Modern UI library
|
|
112
|
+
Vite β Next-generation build tool
|
|
113
|
+
Tailwind CSS β Utility-first styling
|
|
114
|
+
React Router β Routing solution
|
|
115
|
+
Axios β API communication
|
|
116
|
+
ESLint β Code quality and linting
|
|
117
|
+
|
|
118
|
+
Optional: Redux Toolkit, TypeScript
|
|
119
|
+
|
|
120
|
+
π‘ Philosophy
|
|
121
|
+
|
|
122
|
+
React Tailwind AK Kit follows a simple idea:
|
|
123
|
+
Start clean. Scale confidently. Build faster.
|
|
124
|
+
It gives you a professional starting point so your projects feel structured from day one β just like real-world production apps.
|
package/index.js
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import execa from 'execa';
|
|
11
|
+
import figlet from 'figlet';
|
|
12
|
+
import gradient from 'gradient-string';
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = path.dirname(__filename);
|
|
16
|
+
|
|
17
|
+
const program = new Command();
|
|
18
|
+
|
|
19
|
+
async function init() {
|
|
20
|
+
console.log(gradient.pastel.multiline(figlet.textSync('React Tailwind AK Kit', { horizontalLayout: 'full' })));
|
|
21
|
+
console.log(chalk.blue('Welcome to the Ultimate React + Tailwind CLI Generator! π\n'));
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.name('react-tailwind-ak-kit')
|
|
25
|
+
.description('CLI to scaffold production-ready React apps')
|
|
26
|
+
.version('1.0.0')
|
|
27
|
+
.argument('<project-name>', 'Name of the project')
|
|
28
|
+
.action(async (projectName) => {
|
|
29
|
+
try {
|
|
30
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
31
|
+
|
|
32
|
+
if (fs.existsSync(targetDir)) {
|
|
33
|
+
console.error(chalk.red(`\nError: Directory "${projectName}" already exists.`));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const answers = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'confirm',
|
|
40
|
+
name: 'typescript',
|
|
41
|
+
message: 'Do you want to use TypeScript?',
|
|
42
|
+
default: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'redux',
|
|
47
|
+
message: 'Do you want Redux Toolkit configured?',
|
|
48
|
+
default: false,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'confirm',
|
|
52
|
+
name: 'auth',
|
|
53
|
+
message: 'Do you want an Authentication starter (Context + Dummy Pages)?',
|
|
54
|
+
default: false,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'confirm',
|
|
58
|
+
name: 'shadcn',
|
|
59
|
+
message: 'Do you want to include ShadCN UI utils (clsx, tailwind-merge)?',
|
|
60
|
+
default: false,
|
|
61
|
+
},
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
await generateProject(projectName, targetDir, answers);
|
|
65
|
+
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error(chalk.red('\nAn error occurred:', error));
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
program.parse(process.argv);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function generateProject(projectName, targetDir, options) {
|
|
76
|
+
const spinner = ora('Initializing project...').start();
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
// 1. Create Vite App
|
|
80
|
+
spinner.stop();
|
|
81
|
+
console.log(chalk.blue('Creating Vite app...'));
|
|
82
|
+
const template = options.typescript ? 'react-ts' : 'react';
|
|
83
|
+
// Use npm create instead of npx to avoid "cb.apply is not a function" errors
|
|
84
|
+
await execa('npm', ['create', 'vite@latest', projectName, '--', '--template', template], { stdio: 'inherit' });
|
|
85
|
+
|
|
86
|
+
// 2. Install Dependencies
|
|
87
|
+
console.log(chalk.blue('Installing core dependencies...'));
|
|
88
|
+
process.chdir(targetDir);
|
|
89
|
+
|
|
90
|
+
const dependencies = [
|
|
91
|
+
'axios',
|
|
92
|
+
'react-router-dom',
|
|
93
|
+
'clsx',
|
|
94
|
+
'tailwind-merge',
|
|
95
|
+
'lucide-react'
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
const devDependencies = [
|
|
99
|
+
'tailwindcss@^3.4.17',
|
|
100
|
+
'postcss',
|
|
101
|
+
'autoprefixer',
|
|
102
|
+
'prettier',
|
|
103
|
+
'eslint-config-prettier',
|
|
104
|
+
'eslint-plugin-prettier'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
if (options.redux) {
|
|
108
|
+
dependencies.push('@reduxjs/toolkit', 'react-redux');
|
|
109
|
+
}
|
|
110
|
+
await execa('npm', ['install', ...dependencies], { stdio: 'inherit' });
|
|
111
|
+
await execa('npm', ['install', '-D', ...devDependencies], { stdio: 'inherit' });
|
|
112
|
+
|
|
113
|
+
// 3. Initialize Tailwind
|
|
114
|
+
console.log(chalk.blue('Initializing Tailwind CSS...'));
|
|
115
|
+
// await execa('npx', ['tailwindcss', 'init', '-p'], { stdio: 'inherit' }); // Removed due to v4 bin issue/redundancy
|
|
116
|
+
|
|
117
|
+
// 4. Setup Folder Structure
|
|
118
|
+
console.log(chalk.blue('Setting up architecture...'));
|
|
119
|
+
await setupFolderStructure(targetDir, options);
|
|
120
|
+
|
|
121
|
+
// 5. Create Configuration Files
|
|
122
|
+
console.log(chalk.blue('Creating configuration files...'));
|
|
123
|
+
await createConfigFiles(targetDir, options);
|
|
124
|
+
|
|
125
|
+
console.log(chalk.green(`\nSuccessfully created project: ${projectName}`));
|
|
126
|
+
|
|
127
|
+
console.log('\nTo get started:\n');
|
|
128
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
|
129
|
+
console.log(chalk.cyan(' npm run dev\n'));
|
|
130
|
+
|
|
131
|
+
} catch (err) {
|
|
132
|
+
if (spinner.isSpinning) spinner.fail(chalk.red('Failed to generate project.'));
|
|
133
|
+
console.error(chalk.red(err));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function setupFolderStructure(targetDir, options) {
|
|
139
|
+
const srcDir = path.join(targetDir, 'src');
|
|
140
|
+
|
|
141
|
+
// Clean default src
|
|
142
|
+
await fs.emptyDir(srcDir);
|
|
143
|
+
|
|
144
|
+
const folders = [
|
|
145
|
+
'assets',
|
|
146
|
+
'components/ui',
|
|
147
|
+
'components/layout',
|
|
148
|
+
'pages',
|
|
149
|
+
'hooks',
|
|
150
|
+
'services',
|
|
151
|
+
'context',
|
|
152
|
+
'routes',
|
|
153
|
+
'utils',
|
|
154
|
+
'store' // Optional, but good to have if Redux
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
for (const folder of folders) {
|
|
158
|
+
await fs.ensureDir(path.join(srcDir, folder));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function createConfigFiles(targetDir, options) {
|
|
163
|
+
const srcDir = path.join(targetDir, 'src');
|
|
164
|
+
const ext = options.typescript ? 'tsx' : 'jsx';
|
|
165
|
+
const jsExt = options.typescript ? 'ts' : 'js';
|
|
166
|
+
|
|
167
|
+
// 1. Tailwind Config
|
|
168
|
+
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
169
|
+
export default {
|
|
170
|
+
content: [
|
|
171
|
+
"./index.html",
|
|
172
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
173
|
+
],
|
|
174
|
+
theme: {
|
|
175
|
+
extend: {
|
|
176
|
+
colors: {
|
|
177
|
+
primary: '#3b82f6',
|
|
178
|
+
secondary: '#64748b',
|
|
179
|
+
accent: '#f59e0b',
|
|
180
|
+
background: '#f8fafc',
|
|
181
|
+
surface: '#ffffff',
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
plugins: [],
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
await fs.writeFile(path.join(targetDir, 'tailwind.config.js'), tailwindConfig);
|
|
189
|
+
|
|
190
|
+
const postcssConfig = `export default {
|
|
191
|
+
plugins: {
|
|
192
|
+
tailwindcss: {},
|
|
193
|
+
autoprefixer: {},
|
|
194
|
+
},
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
await fs.writeFile(path.join(targetDir, 'postcss.config.js'), postcssConfig);
|
|
198
|
+
|
|
199
|
+
// 2. index.css
|
|
200
|
+
const indexCss = `@tailwind base;
|
|
201
|
+
@tailwind components;
|
|
202
|
+
@tailwind utilities;
|
|
203
|
+
|
|
204
|
+
@layer base {
|
|
205
|
+
body {
|
|
206
|
+
@apply bg-background text-slate-900 antialiased;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
`;
|
|
210
|
+
await fs.writeFile(path.join(srcDir, 'index.css'), indexCss);
|
|
211
|
+
|
|
212
|
+
// 3. Utils (cn)
|
|
213
|
+
const utilsContent = `import { clsx } from "clsx";
|
|
214
|
+
import { twMerge } from "tailwind-merge";
|
|
215
|
+
|
|
216
|
+
export function cn(...inputs) {
|
|
217
|
+
return twMerge(clsx(inputs));
|
|
218
|
+
}
|
|
219
|
+
`;
|
|
220
|
+
await fs.writeFile(path.join(srcDir, `utils/cn.${jsExt}`), utilsContent);
|
|
221
|
+
|
|
222
|
+
// 4. Components - Layout (Navbar)
|
|
223
|
+
const navbarContent = `import React from 'react';
|
|
224
|
+
import { Link } from 'react-router-dom';
|
|
225
|
+
import { cn } from '../../utils/cn';
|
|
226
|
+
|
|
227
|
+
const Navbar = () => {
|
|
228
|
+
return (
|
|
229
|
+
<nav className="bg-surface shadow-sm border-b border-gray-200">
|
|
230
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
231
|
+
<div className="flex justify-between h-16">
|
|
232
|
+
<div className="flex">
|
|
233
|
+
<div className="flex-shrink-0 flex items-center">
|
|
234
|
+
<Link to="/" className="text-2xl font-bold text-primary">Brand</Link>
|
|
235
|
+
</div>
|
|
236
|
+
<div className="hidden sm:ml-6 sm:flex sm:space-x-8">
|
|
237
|
+
<Link to="/" className="text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 border-primary text-sm font-medium">
|
|
238
|
+
Home
|
|
239
|
+
</Link>
|
|
240
|
+
<Link to="/about" className="text-gray-500 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium">
|
|
241
|
+
About
|
|
242
|
+
</Link>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
<div className="flex items-center">
|
|
246
|
+
<button className="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors">
|
|
247
|
+
Action
|
|
248
|
+
</button>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
</nav>
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export default Navbar;
|
|
257
|
+
`;
|
|
258
|
+
await fs.writeFile(path.join(srcDir, `components/layout/Navbar.${ext}`), navbarContent);
|
|
259
|
+
|
|
260
|
+
// 5. Pages - Home
|
|
261
|
+
const homeContent = `import React from 'react';
|
|
262
|
+
import { cn } from '../utils/cn';
|
|
263
|
+
|
|
264
|
+
const Home = () => {
|
|
265
|
+
return (
|
|
266
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
|
267
|
+
<div className="text-center">
|
|
268
|
+
<h1 className="text-4xl tracking-tight font-extrabold text-gray-900 sm:text-5xl md:text-6xl">
|
|
269
|
+
<span className="block xl:inline">Ready to build</span>{' '}
|
|
270
|
+
<span className="block text-primary xl:inline">Something Amazing?</span>
|
|
271
|
+
</h1>
|
|
272
|
+
<p className="mt-3 max-w-md mx-auto text-base text-gray-500 sm:text-lg md:mt-5 md:text-xl md:max-w-3xl">
|
|
273
|
+
This is a production-ready template pre-configured with Tailwind CSS, React Router, Axios, and best practices.
|
|
274
|
+
</p>
|
|
275
|
+
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
|
|
276
|
+
<div className="rounded-md shadow">
|
|
277
|
+
<a href="#" className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-primary hover:bg-blue-700 md:py-4 md:text-lg md:px-10">
|
|
278
|
+
Get started
|
|
279
|
+
</a>
|
|
280
|
+
</div>
|
|
281
|
+
<div className="mt-3 rounded-md shadow sm:mt-0 sm:ml-3">
|
|
282
|
+
<a href="#" className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-primary bg-white hover:bg-gray-50 md:py-4 md:text-lg md:px-10">
|
|
283
|
+
Learn more
|
|
284
|
+
</a>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
export default Home;
|
|
293
|
+
`;
|
|
294
|
+
await fs.writeFile(path.join(srcDir, `pages/Home.${ext}`), homeContent);
|
|
295
|
+
|
|
296
|
+
// 6. Config - Routes
|
|
297
|
+
const routesContent = `import React from 'react';
|
|
298
|
+
import { Routes, Route } from 'react-router-dom';
|
|
299
|
+
import Navbar from '../components/layout/Navbar';
|
|
300
|
+
import Home from '../pages/Home';
|
|
301
|
+
|
|
302
|
+
const AppRoutes = () => {
|
|
303
|
+
return (
|
|
304
|
+
<>
|
|
305
|
+
<Navbar />
|
|
306
|
+
<Routes>
|
|
307
|
+
<Route path="/" element={<Home />} />
|
|
308
|
+
<Route path="/about" element={<div className="p-8 text-center">About Page</div>} />
|
|
309
|
+
<Route path="*" element={<div className="p-8 text-center">404 Not Found</div>} />
|
|
310
|
+
</Routes>
|
|
311
|
+
</>
|
|
312
|
+
);
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export default AppRoutes;
|
|
316
|
+
`;
|
|
317
|
+
await fs.writeFile(path.join(srcDir, `routes/AppRoutes.${ext}`), routesContent);
|
|
318
|
+
|
|
319
|
+
// 7. Config - App & Main
|
|
320
|
+
const appContent = `import React from 'react';
|
|
321
|
+
import AppRoutes from './routes/AppRoutes';
|
|
322
|
+
|
|
323
|
+
function App() {
|
|
324
|
+
return (
|
|
325
|
+
<div className="min-h-screen bg-background">
|
|
326
|
+
<AppRoutes />
|
|
327
|
+
</div>
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export default App;
|
|
332
|
+
`;
|
|
333
|
+
await fs.writeFile(path.join(srcDir, `App.${ext}`), appContent);
|
|
334
|
+
|
|
335
|
+
const mainContent = `import React from 'react';
|
|
336
|
+
import ReactDOM from 'react-dom/client';
|
|
337
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
338
|
+
${options.redux ? "import { Provider } from 'react-redux';\nimport { store } from './store/store';" : ''}
|
|
339
|
+
import App from './App';
|
|
340
|
+
import './index.css';
|
|
341
|
+
|
|
342
|
+
ReactDOM.createRoot(document.getElementById('root')).render(
|
|
343
|
+
<React.StrictMode>
|
|
344
|
+
${options.redux ? '<Provider store={store}>' : ''}
|
|
345
|
+
<BrowserRouter>
|
|
346
|
+
<App />
|
|
347
|
+
</BrowserRouter>
|
|
348
|
+
${options.redux ? '</Provider>' : ''}
|
|
349
|
+
</React.StrictMode>,
|
|
350
|
+
);
|
|
351
|
+
`;
|
|
352
|
+
await fs.writeFile(path.join(srcDir, `main.${ext}`), mainContent);
|
|
353
|
+
|
|
354
|
+
// 8. Service - Axios
|
|
355
|
+
const axiosContent = `import axios from 'axios';
|
|
356
|
+
|
|
357
|
+
const api = axios.create({
|
|
358
|
+
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api',
|
|
359
|
+
timeout: 10000,
|
|
360
|
+
headers: {
|
|
361
|
+
'Content-Type': 'application/json',
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Request interceptor
|
|
366
|
+
api.interceptors.request.use(
|
|
367
|
+
(config) => {
|
|
368
|
+
// You can add auth token here
|
|
369
|
+
// const token = localStorage.getItem('token');
|
|
370
|
+
// if (token) {
|
|
371
|
+
// config.headers.Authorization = \`Bearer \${token}\`;
|
|
372
|
+
// }
|
|
373
|
+
return config;
|
|
374
|
+
},
|
|
375
|
+
(error) => {
|
|
376
|
+
return Promise.reject(error);
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
// Response interceptor
|
|
381
|
+
api.interceptors.response.use(
|
|
382
|
+
(response) => response,
|
|
383
|
+
(error) => {
|
|
384
|
+
// Handle global errors here
|
|
385
|
+
return Promise.reject(error);
|
|
386
|
+
}
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
export default api;
|
|
390
|
+
`;
|
|
391
|
+
await fs.writeFile(path.join(srcDir, `services/api.${jsExt}`), axiosContent);
|
|
392
|
+
|
|
393
|
+
// 9. Redux (if selected)
|
|
394
|
+
if (options.redux) {
|
|
395
|
+
const storeContent = `import { configureStore } from '@reduxjs/toolkit';
|
|
396
|
+
|
|
397
|
+
export const store = configureStore({
|
|
398
|
+
reducer: {
|
|
399
|
+
// counter: counterReducer,
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
`;
|
|
403
|
+
await fs.writeFile(path.join(srcDir, `store/store.${jsExt}`), storeContent);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Run the initialization
|
|
408
|
+
init();
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-tailwind-ak-kit",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "A CLI to scaffold production-ready React apps with Tailwind CSS, Vite, and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"react-tailwind-ak-kit": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"react",
|
|
14
|
+
"vite",
|
|
15
|
+
"tailwind",
|
|
16
|
+
"cli",
|
|
17
|
+
"scaffold",
|
|
18
|
+
"boilerplate"
|
|
19
|
+
],
|
|
20
|
+
"author": "Adarsh Yadav",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"chalk": "^4.1.2",
|
|
24
|
+
"commander": "^11.1.0",
|
|
25
|
+
"execa": "^5.1.1",
|
|
26
|
+
"fs-extra": "^11.2.0",
|
|
27
|
+
"inquirer": "^8.2.6",
|
|
28
|
+
"ora": "^5.4.1",
|
|
29
|
+
"figlet": "^1.7.0",
|
|
30
|
+
"gradient-string": "^2.0.2"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|