From acf6fdfd105bba476efb171f8cd92d752ecad691 Mon Sep 17 00:00:00 2001 From: Hagop Jamkojian Date: Fri, 25 Dec 2020 19:49:54 +0200 Subject: [PATCH] Add script to create app using npm init --- .eslintignore | 1 + .gitignore | 3 -- bin/createNodejsApp.js | 111 +++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 bin/createNodejsApp.js diff --git a/.eslintignore b/.eslintignore index 3c3629e6..ed4598e7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ node_modules +bin diff --git a/.gitignore b/.gitignore index 2da451ac..e516023e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Dependencies node_modules -# package-lock.json (use yarn.lock instead) -package-lock.json - # yarn error logs yarn-error.log diff --git a/bin/createNodejsApp.js b/bin/createNodejsApp.js new file mode 100644 index 00000000..38c41cb8 --- /dev/null +++ b/bin/createNodejsApp.js @@ -0,0 +1,111 @@ +#!/usr/bin/env node +const util = require('util'); +const path = require('path'); +const fs = require('fs'); +const { execSync } = require('child_process') + +// Utility functions +const exec = util.promisify(require("child_process").exec); +async function runCmd(command) { + try { + const { stdout, stderr } = await exec(command); + console.log(stdout); + console.log(stderr); + } catch { + (error) => { + console.log(error); + }; + } +} + +async function hasYarn() { + try { + await execSync('yarnpkg --version', { stdio: 'ignore' }); + return true; + } catch { + return false; + } +} + +// Validate arguments +if (process.argv.length < 3) { + console.log('Please specify the target project directory.'); + console.log('For example:'); + console.log(' npx create-nodejs-app my-app'); + console.log(' OR'); + console.log(' npm init nodejs-app my-app'); + process.exit(1); +} + +// Define constants +const ownPath = process.cwd(); +const folderName = process.argv[2]; +const appPath = path.join(ownPath, folderName); +const repo = 'https://github.com/hagopj13/node-express-mongoose-boilerplate.git'; + +// Check if directory already exists +try { + fs.mkdirSync(appPath); +} catch (err) { + if (err.code === 'EEXIST') { + console.log('Directory already exists. Please choose another name for the project.'); + } else { + console.log(error); + } + process.exit(1); +} + +async function setup() { + try { + // Clone repo + console.log(`Downloading files from repo ${repo}`); + await runCmd(`git clone --depth 1 ${repo} ${folderName}`); + console.log('Cloned successfully.'); + console.log(''); + + // Change directory + process.chdir(appPath); + + // Install dependencies + const useYarn = await hasYarn(); + console.log('Installing dependencies...'); + if (useYarn) { + await runCmd('yarn install'); + } else { + await runCmd('npm install'); + } + console.log('Dependencies installed successfully.'); + console.log(); + + // Copy envornment variables + fs.copyFileSync(path.join(appPath, '.env.example'), path.join(appPath, '.env')) + console.log('Environment files copied.'); + + // Delete .git folder + await runCmd('npx rimraf ./.git'); + + // Remove extra files + fs.unlinkSync(path.join(appPath, 'CHANGELOG.md')); + fs.unlinkSync(path.join(appPath, 'CODE_OF_CONDUCT.md')); + fs.unlinkSync(path.join(appPath, 'CONTRIBUTING.md')); + fs.unlinkSync(path.join(appPath, 'bin', 'createNodejsApp.js')); + fs.rmdirSync(path.join(appPath, 'bin')); + if (!useYarn) { + fs.unlinkSync(path.join(appPath, 'yarn.lock')); + } + + console.log('Installation is now complete!'); + console.log(); + + console.log('We suggest that you start by typing:'); + console.log(` cd ${folderName}`); + console.log(useYarn ? ' yarn dev' : ' npm run dev'); + console.log(); + console.log('Enjoy your production-ready Node.js app, which already supports a large number of ready-made features!'); + console.log('Check README.md for more info.'); + } catch (error) { + console.log(error); + } +} + +setup(); diff --git a/package.json b/package.json index ccf0f4e5..a081b2a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { - "name": "node-express-mongoose-boilerplate", + "name": "create-nodejs-express-app", "version": "1.5.0", "description": "A boilerplate for building production-ready RESTful APIs using Node.js, Express, and Mongoose", + "bin": "bin/createNodejsApp.js", "main": "src/index.js", "repository": "https://github.com/hagopj13/node-express-mongoose-boilerplate.git", "author": "Hagop Jamkojian ",