react-vite-template-generator
Version:
A React project generator using Vite, designed to provide an optimized folder structure right from the start
136 lines (120 loc) • 4.64 kB
JavaScript
#!/usr/bin/env node
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer');
(async () => {
const chalk = (await import('chalk')).default;
// Validate project name input
const projectName = process.argv[2];
if (!projectName) {
console.error(chalk.red('❌ Please provide a project name: npx create-react-vite-template <project-name>'));
process.exit(1);
}
try {
console.log(chalk.bold.blue(`🚀 Creating React project: ${projectName}`));
// Ask user preferences using Inquirer
const answers = await inquirer.default.prompt([
{
type: 'list',
name: 'template',
message: 'Choose a template:',
choices: ['Basic', 'Advanced', 'Full-Stack'],
},
{
type: 'confirm',
name: 'installTailwind',
message: 'Do you want to install TailwindCSS?',
default: false,
},
{
type: 'confirm',
name: 'installEslint',
message: 'Do you want to install ESLint?',
default: false,
},
{
type: 'confirm',
name: 'installRouter',
message: 'Do you want to install React Router?',
default: false,
}
]);
// Create base Vite React project
console.log(chalk.yellow('🛠️ Generating Vite React project...'));
execSync(`npm create vite@latest ${projectName} -- --template react`, { stdio: 'inherit' });
process.chdir(projectName);
// Create custom folder structure
console.log(chalk.yellow('📂 Creating folder structure...'));
const folders = [
'src/assets',
'src/components',
'src/pages',
'src/hooks',
'src/context',
'src/services',
'src/styles'
];
folders.forEach(folder => {
fs.mkdirSync(path.join(process.cwd(), folder), { recursive: true });
});
// Add example files
console.log(chalk.yellow('📝 Adding example files...'));
fs.writeFileSync('src/hooks/useExample.js', 'export const useExample = () => {};');
fs.writeFileSync('src/context/AppContext.jsx', 'import { createContext } from "react";\nexport const AppContext = createContext();');
fs.writeFileSync('src/styles/global.css', '/* Global styles */');
// Install TailwindCSS if selected
if (answers.installTailwind) {
console.log(chalk.green('✨ Installing TailwindCSS...'));
execSync('npm install -D tailwindcss postcss autoprefixer', { stdio: 'inherit' });
execSync('npx tailwindcss init -p', { stdio: 'inherit' });
fs.writeFileSync('tailwind.config.js', `
module.exports = {
content: ['./index.html', './src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
}
`);
}
// Install ESLint if selected
if (answers.installEslint) {
console.log(chalk.green('✨ Installing ESLint...'));
execSync('npm install -D eslint', { stdio: 'inherit' });
execSync('npx eslint --init', { stdio: 'inherit' });
}
// Install React Router if selected
if (answers.installRouter) {
console.log(chalk.green('✨ Installing React Router...'));
execSync('npm install react-router-dom', { stdio: 'inherit' });
fs.writeFileSync('src/App.jsx', `
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default App;
`);
fs.writeFileSync('src/pages/Home.jsx', 'export default function Home() { return <h1>Home</h1>; }');
fs.writeFileSync('src/pages/About.jsx', 'export default function About() { return <h1>About</h1>; }');
}
// Final instructions
console.log(chalk.bold.green('✅ Project created successfully!'));
console.log(chalk.blueBright(`👉 cd ${projectName}`));
console.log(chalk.blueBright('👉 npm install'));
console.log(chalk.blueBright('👉 npm run dev'));
console.log(chalk.magentaBright('✨ Happy coding!'));
} catch (error) {
console.error(chalk.red('❌ Error creating project:'), error.message);
process.exit(1);
}
})();