UNPKG

create-bfe-cttq

Version:

CTTQ大前端脚手架项目

140 lines (133 loc) 5.17 kB
/** * 项目创造器,负责调度 */ const EventEmitter = require("events"); const fs = require("fs-extra"); const path = require("path"); const ora = require("ora"); const prompts = require("prompts"); const { red, green, bold } = require("kolorist") const { logWithSpinner, succeedSpinner, failSpinner } = require("./util/spinner"); const { getAllPlugins } = require("./util/plugins") const Promptor = require("./Promptor"); const Generator = require("./Generator"); const generateReadme = require("./util/generateReadme") const generateChangelog = require("./util/generateChangelog") const writeFileTree = require("./util/writeFileTree") const Package = require("../../package.json"); const TemplateManager = require("./TemplateManager"); module.exports = class Creator extends EventEmitter { constructor(context) { super(); this.context = context; this.plugins = getAllPlugins(); } async create() { // cli问答 const promptor = new Promptor(this.plugins); await promptor.show(); if (Object.keys(promptor.answers).length <= 0) { return; } // 项目路径创建方式 const lowerCaseName = promptor.answers.name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-"); let targetDir = path.resolve(this.context, lowerCaseName || "."); if (path.basename(this.context).toLowerCase() == lowerCaseName) { const { context } = await prompts( [{ name: "context", type: "select", message: `请选择创建项目的目录:`, choices: [ { title: "子目录下", value: targetDir, description: targetDir, }, { title: "当前目录下", value: this.context, description: this.context, } ], hint: "- ↑ ↓ 选择. 回车 确认", }], { onCancel: () => { throw new Error(red("✖") + " 取消创建项目"); }, }, ); targetDir = context; } if (targetDir != this.context && fs.existsSync(targetDir)) { const { action } = await prompts( [{ name: "action", type: "select", message: `已经存在该目录 ${green(targetDir)},请选择一种处理方式:`, choices: [ { title: "重写", value: "overwrite", description: "删除现有项目所有文件,然后重新创建项目", }, { title: "合并", value: "merge", description: "保留现有目录,合并项目下文件,存在同名文件,则替换该文件", }, { title: "取消", value: "cancel", description: "取消创建项目", selected: true } ], hint: "- ↑ ↓ 选择. 回车 确认", }], { onCancel: () => { throw new Error(red("✖") + " 取消创建项目"); }, }, ); if ("cancel" == action) { throw new Error(red("✖") + " 取消创建项目"); } else if ("overwrite" == action) { await fs.remove(targetDir) } } const pkg = { name: lowerCaseName, version: "0.0.0", description: promptor.answers.description, private: true, devDependencies: {}, engines: { cli: Package.version, template: process.env.CTTQ_TEMPLATE_VERSION, } } logWithSpinner("开始创建项目") // 生成项目 const generator = new Generator(targetDir, this.plugins, pkg, promptor.answers); await generator.generate(); for (const cb of generator.createdCallbacks) { await cb() } //写入CHANGELOG if (!generator.files['CHANGELOG.md']) { await writeFileTree(targetDir, { "CHANGELOG.md": generateChangelog(pkg) }); } // 写入README if (!generator.files['README.md']) { await writeFileTree(targetDir, { "README.md": generateReadme(pkg) }); } succeedSpinner("项目创建成功:"+green(targetDir)); } }