UNPKG

my-costom

Version:

Advanced project template generator CLI with interactive selection and custom Hello World templates

270 lines (225 loc) • 6.97 kB
#!/usr/bin/env node const { execSync } = require('child_process'); const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); // Enhanced template list with more options const templates = { '1': { name: 'Next.js', cmd: 'npx create-next-app@latest', description: 'Full-stack React framework with SSR/SSG' }, '2': { name: 'React + Vite', cmd: 'npm create vite@latest', description: 'Fast React development with Vite' }, '3': { name: 'React Router', cmd: 'npx create-react-app', description: 'React SPA with routing capabilities', postInstall: 'npm install react-router-dom' }, '4': { name: 'Astro', cmd: 'npm create astro@latest', description: 'Static site generator with islands architecture' }, '5': { name: 'Remix', cmd: 'npx create-remix@latest', description: 'Full-stack web framework focused on web standards' } }; console.log('šŸš€ Enhanced Project Generator\n'); console.log('Available templates:'); Object.entries(templates).forEach(([key, template]) => { console.log(`${key}. ${template.name}`); console.log(` ${template.description}`); console.log(''); }); rl.question('Select a template (1-5): ', (choice) => { if (!templates[choice]) { console.log('āŒ Invalid choice! Please select 1-5.'); process.exit(1); } const selectedTemplate = templates[choice]; rl.question('Project name: ', (name) => { if (!name.trim()) { console.log('āŒ Project name is required!'); process.exit(1); } // Validate project name (basic validation) if (!/^[a-zA-Z0-9-_]+$/.test(name)) { console.log('āŒ Project name should only contain letters, numbers, hyphens, and underscores.'); process.exit(1); } console.log(`\nšŸ”§ Creating ${selectedTemplate.name} project: ${name}`); console.log(`šŸ“ ${selectedTemplate.description}\n`); try { // Create the project execSync(`${selectedTemplate.cmd} ${name}`, { stdio: 'inherit' }); // Handle post-installation steps if (selectedTemplate.postInstall) { console.log(`\nšŸ“¦ Installing additional dependencies...`); process.chdir(name); execSync(selectedTemplate.postInstall, { stdio: 'inherit' }); // For React Router, create a basic routing setup if (selectedTemplate.name === 'React Router') { createReactRouterSetup(); } } console.log(`\nāœ… Project ${name} created successfully!`); console.log(`\nšŸš€ Next steps:`); console.log(` cd ${name}`); if (!selectedTemplate.postInstall) { console.log(` npm install`); } console.log(` npm run dev` + (selectedTemplate.name === 'React Router' ? ' (or npm start)' : '')); // Template-specific instructions if (selectedTemplate.name === 'React Router') { console.log(`\nšŸ“š React Router features added:`); console.log(` • Basic routing setup in src/App.js`); console.log(` • Example pages: Home, About, Contact`); console.log(` • Navigation component`); } } catch (error) { console.error('āŒ Failed to create project:', error.message); process.exit(1); } rl.close(); }); }); // Function to create React Router setup function createReactRouterSetup() { const fs = require('fs'); const path = require('path'); // Create App.js with routing const appContent = `import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Navigation from './components/Navigation'; import Home from './pages/Home'; import About from './pages/About'; import Contact from './pages/Contact'; import './App.css'; function App() { return ( <Router> <div className="App"> <Navigation /> <main className="main-content"> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </main> </div> </Router> ); } export default App;`; // Create directories if (!fs.existsSync('src/components')) fs.mkdirSync('src/components', { recursive: true }); if (!fs.existsSync('src/pages')) fs.mkdirSync('src/pages', { recursive: true }); // Write App.js fs.writeFileSync('src/App.js', appContent); // Create Navigation component const navContent = `import React from 'react'; import { Link } from 'react-router-dom'; import './Navigation.css'; function Navigation() { return ( <nav className="navigation"> <div className="nav-container"> <Link to="/" className="nav-logo">My App</Link> <div className="nav-links"> <Link to="/" className="nav-link">Home</Link> <Link to="/about" className="nav-link">About</Link> <Link to="/contact" className="nav-link">Contact</Link> </div> </div> </nav> ); } export default Navigation;`; fs.writeFileSync('src/components/Navigation.js', navContent); // Create page components const homeContent = `import React from 'react'; function Home() { return ( <div className="page"> <h1>Welcome Home</h1> <p>This is the home page of your React Router application.</p> </div> ); } export default Home;`; const aboutContent = `import React from 'react'; function About() { return ( <div className="page"> <h1>About Us</h1> <p>Learn more about our company and mission.</p> </div> ); } export default About;`; const contactContent = `import React from 'react'; function Contact() { return ( <div className="page"> <h1>Contact Us</h1> <p>Get in touch with our team.</p> </div> ); } export default Contact;`; fs.writeFileSync('src/pages/Home.js', homeContent); fs.writeFileSync('src/pages/About.js', aboutContent); fs.writeFileSync('src/pages/Contact.js', contactContent); // Create basic CSS for navigation const navCss = `.navigation { background-color: #282c34; padding: 1rem 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .nav-container { max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; padding: 0 2rem; } .nav-logo { color: #61dafb; font-size: 1.5rem; font-weight: bold; text-decoration: none; } .nav-links { display: flex; gap: 2rem; } .nav-link { color: white; text-decoration: none; padding: 0.5rem 1rem; border-radius: 4px; transition: background-color 0.3s; } .nav-link:hover { background-color: rgba(97, 218, 251, 0.1); } .page { padding: 2rem; max-width: 1200px; margin: 0 auto; }`; fs.writeFileSync('src/components/Navigation.css', navCss); console.log('šŸ“ React Router setup files created successfully!'); }