UNPKG

@artegha/create-node-server

Version:

Create Node servers with no build configuration.

251 lines (215 loc) 7.55 kB
import chalk from 'chalk' import fs from 'fs-extra' import os from 'os' import path from 'path' import spawn from 'cross-spawn' import tools from '../utils/tools' import packageJson from '../package.json' export default (server: Server) => { const appPackage: { [key: string]: any } = packageJson server.useYarn = fs.existsSync(path.join(server.root, 'yarn.lock')) if (!server.templateName) { console.log('') console.error( `A template was not provided. Using default template ${chalk.cyan('cns-template-typescript-express')}.` ) } const templatePath = path.dirname(require.resolve(`${server.templateName}/package.json`, { paths: [server.root] })) const templateJsonPath = path.join(templatePath, 'template.json') let templateJson: { [key: string]: any } = {} if (fs.existsSync(templateJsonPath)) { templateJson = require(templateJsonPath) } const templatePackage = templateJson.package || {} if (templateJson.dependencies) { templatePackage.dependencies = templateJson.dependencies } if (templateJson.scripts) { templatePackage.scripts = templateJson.scripts } if (templateJson.devDependencies) { templatePackage.devDependencies = templateJson.devDependencies } // Keys to ignore in templatePackage const templatePackageBlacklist = [ 'name', 'version', 'description', 'keywords', 'bugs', 'license', 'author', 'contributors', 'files', 'browser', 'bin', 'man', 'directories', 'repository', 'peerDependencies', 'bundledDependencies', 'optionalDependencies', 'engineStrict', 'os', 'cpu', 'preferGlobal', 'private', 'publishConfig', ] // Keys from templatePackage that will be merged with appPackage const templatePackageToMerge = ['dependencies', 'scripts', 'devDependencies'] // Keys from templatePackage that will be added to appPackage, // replacing any existing entries. const templatePackageToReplace = Object.keys(templatePackage).filter((key) => { return !templatePackageBlacklist.includes(key) && !templatePackageToMerge.includes(key) }) // Copy over some of the dependencies appPackage.dependencies = appPackage.dependencies || {} // Setup the script rules appPackage.scripts = templatePackage.scripts || {} // Copy over some of the devDependencies appPackage.devDependencies = appPackage.devDependencies || {} // Update scripts for Yarn users if (server.useYarn) { appPackage.scripts = Object.entries(appPackage.scripts).reduce( (acc, [key, value]: any) => ({ ...acc, [key]: value.replace(/(npm run |npm )/, 'yarn '), }), {} ) } // Add templatePackage keys/values to appPackage, replacing existing entries templatePackageToReplace.forEach((key) => { appPackage[key] = templatePackage[key] }) // Overwrite the package.json fs.writeFileSync(path.join(server.root, 'package.json'), JSON.stringify(appPackage, null, 2) + os.EOL) // Replace README.md and remane the old one const readmeExists = fs.existsSync(path.join(server.root, 'README.md')) if (readmeExists) { fs.renameSync(path.join(server.root, 'README.md'), path.join(server.root, 'README.old.md')) } // Copy the files from template/ the user const templateDir = path.join(templatePath, 'template') if (fs.existsSync(templateDir)) { fs.copySync(templateDir, server.root) } else { throw new Error(`Could not locate supplied template: ${chalk.green(templateDir)}`) } // modifies README.md commands based on user used package manager. if (server.useYarn) { try { const readme = fs.readFileSync(path.join(server.root, 'README.md'), 'utf8') fs.writeFileSync(path.join(server.root, 'README.md'), readme.replace(/(npm run |npm )/g, 'yarn '), 'utf8') } catch (err) { throw new Error(err) } } const gitignoreExists = fs.existsSync(path.join(server.root, '.gitignore')) if (gitignoreExists) { // Append if there's already a `.gitignore` file there const data = fs.readFileSync(path.join(server.root, 'gitignore')) fs.appendFileSync(path.join(server.root, '.gitignore'), data) fs.unlinkSync(path.join(server.root, '.npmignore')) } else { // Rename gitignore after the fact to prevent npm from renaming it to .npmignore // See: https://github.com/npm/npm/issues/1862 fs.moveSync(path.join(server.root, '.npmignore'), path.join(server.root, '.gitignore'), [] as never) } // Initialize git repo const initializedGit = false // if (tools.tryGitInit()) { // initializedGit = true // console.log() // console.log('Initialized a git repository.') // } let command let remove let args if (server.useYarn) { command = 'yarnpkg' remove = 'remove' args = ['add'] } else { command = 'npm' remove = 'uninstall' args = ['install', '--save', server.verbose && '--verbose'].filter((e) => e) } // Install additional template dependencies, if present. const dependenciesToInstall = Object.entries({ ...templatePackage.dependencies, ...templatePackage.devDependencies, }) if (dependenciesToInstall.length) { args = args.concat( dependenciesToInstall.map(([dependency, version]) => { return `${dependency}@${version}` }) ) } // Install template dependencies if (server.templateName && args.length > 1) { console.log() console.log(`Installing template dependencies using ${command}...`) const proc = spawn.sync(command, args, { stdio: 'inherit' }) if (proc.status !== 0) { throw new Error(`\`${command} ${args.join(' ')}\` failed`) } } // if (args.find(arg => arg.includes('typescript'))) { // console.log(); // verifyTypeScriptSetup(); // } // Remove template console.log(`Removing template package using ${command}...`) console.log() const proc = spawn.sync(command, [remove, server.templateName], { stdio: 'inherit', }) if (proc.status !== 0) { throw new Error(`\`${command} ${args.join(' ')}\` failed`) } // Create git commit if git repo was initialized if (initializedGit && tools.tryGitCommit(server.root)) { console.log() console.log('Created git commit.') } // Display the most elegant way to cd. // This needs to handle an undefined server.originalRoot for // backward compatibility with old global-cli's. let cdpath if (server.originalRoot && path.join(server.originalRoot, server.name) === server.root) { cdpath = server.name } else { cdpath = server.root } // Change displayed command to yarn instead of yarnpkg const displayedCommand = server.useYarn ? 'yarn' : 'npm' console.log() console.log(`Success! Created ${chalk.cyan(`${server.name}`)} at ${chalk.cyan(`${server.root}`)} `) console.log('Inside that directory, you can run several commands:') console.log() console.log(chalk.cyan(` ${displayedCommand} start`)) console.log(' Starts the development server.') console.log() console.log(chalk.cyan(` ${displayedCommand} ${server.useYarn ? '' : 'run '}build`)) console.log(' Bundles the server for production.') console.log() console.log(chalk.cyan(` ${displayedCommand} ${server.useYarn ? '' : 'run '}prod`)) console.log(' Bundles and starts the server for production.') // console.log(); // console.log(chalk.cyan(` ${displayedCommand} test`)); // console.log(' Starts the test runner.'); console.log() console.log('We suggest that you begin by typing:') console.log() console.log(chalk.cyan(' cd'), cdpath) console.log(` ${chalk.cyan(`${displayedCommand} start`)}`) if (readmeExists) { console.log() console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`')) } console.log() console.log('Happy hacking!') }