UNPKG

create-swiftstart

Version:

Automate the setup of Vite-React & Next.js projects with a pre-designed boilerplate structure using create-swiftstart. This tool saves your time and provides a clean starting point for your React or Next.js applications.

178 lines (153 loc) 4.5 kB
#!/usr/bin/env node /** * create-swiftstart * Author: Fazle Rabbi (GitHub: fazle-rabbi-dev) * Description: This module generates a pre-designed seo-friendly Vite React & Next.js boilerplate project with a custom folder and file structure. * Version: 1.0.0 * License: MIT * Date: 15 September, 2023; Friday */ /** * NOTE: * The code in this file wasn't written following best practices. 🙈 */ const path = require("path"); const fs = require("fs-extra"); const argv = require("minimist")(process.argv.slice(2)); const readline = require("readline"); const chalk = require("chalk"); const { exec } = require("child_process"); /* Initialized Empty Variable To Store User Input */ let appName; let templateName; let shouldUseAppDir; let nextVersion; /* Clear Terminal And Start App */ const startApp = () => { exec("clear", (error, stdout) => { if (!error) { console.log(stdout); console.clear(); if (argv._.length === 1 && argv.t) { appName = argv._[0]; templateName = argv.t; main(); } else { console.clear(); // console.log(chalk.red("-> Invalid argument.")+chalk.reset()) askAppName(); } } }); }; /* Creating an interface for reading lines of text */ const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); /* Utility Functions */ const displayError = msg => { console.log(chalk.bold.red(`🔴 Oops! ${msg}`)); exec("sleep 1", (error, stdout) => { console.log(stdout) startApp(); }) }; const question = text => { return `${chalk.cyan("? ")}${text}${chalk.gray(" > ")}`; }; /* Appname Prompt */ const askAppName = () => { rl.question(question("Project name:"), answer => { appName = answer; askChooseTemplate(); }); }; /* Choose Template Prompt */ const askChooseTemplate = () => { const options = `${chalk.bold.green("Which template would you like to use?")} r. ${chalk.yellow("React.js")} n. ${chalk.yellow("Next.js")} ` rl.question(question(options), answer => { templateName = answer; if (["n", "next"].includes(answer)) { askShouldUseAppDir(); } else { main(); } }); }; /* App directory usage prompt */ const askShouldUseAppDir = () => { rl.question(question("Would you like to use app dir:(y/n)"), answer => { if (answer === "y") { shouldUseAppDir = true; } else { shouldUseAppDir = false; } main(); // Close the readline interface rl.close(); }); }; /* Main Function To Generate Boilerplate Project */ const main = () => { if (shouldUseAppDir === undefined && ["next", "n"].includes(templateName)) { return askShouldUseAppDir(); } let sourceDir; const changeSource = name => { const newSrc = path.join(__dirname, name); sourceDir = newSrc; }; if (!appName && !templateName) { return displayError("something went wrong"); } if (!["r", "n", "react", "next"].includes(templateName)) { return displayError("invalid option"); } if (["r", "react"].includes(templateName)) { changeSource("react-templates/react_template"); } else { if (shouldUseAppDir) { changeSource("nextjs-templates/next_template_appdir"); } else { changeSource("nextjs-templates/next_template_pagesdir"); } } try { const targetDir = path.join(process.cwd(), appName); fs.mkdirSync(appName); const files = fs.readdirSync(sourceDir); console.log(chalk.cyan(`[*] Scaffolding project in ${targetDir}...`)); fs.copySync(sourceDir, targetDir); // Change app name in package.json let content = fs.readFileSync(`${targetDir}/package.json`, "utf-8"); content = JSON.parse(content); content.name = appName; content = JSON.stringify(content, null, 2); fs.writeFileSync(`${targetDir}/package.json`, content); // Change app name in package-lock.json /*let pkgLockFile = fs.readFileSync( `${targetDir}/package-lock.json`, "utf-8" ); pkgLockFile = JSON.parse(pkgLockFile); pkgLockFile.name = appName; pkgLockFile = JSON.stringify(pkgLockFile, null, 2); fs.writeFileSync(`${targetDir}/package-lock.json`, pkgLockFile); */ console.log(`${chalk.green("✔ ")}Project ${appName} created successful`); console.log(`${chalk.reset()}\nDone. Now run:`); console.log(` cd ${appName} bash install.sh npm run dev `); process.exit(0); } catch (e) { displayError(e.message); } }; startApp();