ruilai-cli
Version: 
custom front-end scaffolding/cli
144 lines (130 loc) • 4.72 kB
JavaScript
const fs = require('fs');
const os = require('os');
const path = require('path');
const chalk = require('chalk');
const inquirer = require('inquirer');
const download = require('download-git-repo');
const copyDir = require('copy-dir');
const ora = require("ora");
const rimraf = require("rimraf");
/**
 * @description 下载模版工程
 */
const handleDownload = (name) => {
    const tempDir = path.join(os.tmpdir(), 'template-dir');
    
    inquirer.prompt([
        {
            type: "list",
            name: "type",
            message: "请选择要生成的前端模版",
            choices: [
                { name: "deploy(后台管理系统)", value: "deploy" },
                { name: "screen(大屏可视化项目)", value: "screen" }
            ],
            // filter: function (val) {
            //     return val.toLowerCase();
            // },
        },
    ]).then(answers => {
        const { type } = answers;
        const downloadTarget = tempDir;
        const spinner = ora("正在下载模板,请稍等...");
        spinner.start();
        download(`realaiFe/template#${type}`, downloadTarget, { clone: true }, err => {
            if (err) {
                spinner.fail();
                console.log(chalk.red(err));
                // 删除临时目录
                rimraf.sync(tempDir);
            } else {
                // 删除临时目录下的 .git 文件夹
                const gitFolderInTemp = path.join(downloadTarget, ".git");
                rimraf.sync(gitFolderInTemp);
                // 将临时目录内容复制到目标路径
                copyDir.sync(downloadTarget, name, {
                    utimes: true,
                    mode: true,
                });
                spinner.succeed();
                // 删除临时目录
                rimraf.sync(tempDir);
                const fileName = `${name}/package.json`;
                if (fs.existsSync(fileName)) {
                    const installCommand = "pnpm";
                    const installArgs = ["install"];
                    // 在当前目录下执行安装命令
                    const childProcess = require("child_process");
                    const installSpinner = ora(
                        `正在通过${installCommand}安装项目依赖,请稍等...`
                    );
                    installSpinner.start();
                    childProcess.execFile(
                        installCommand,
                        installArgs,
                        { cwd: name },
                        (installError) => {
                            if (installError) {
                                installSpinner.fail();
                                console.log(chalk.red(installError));
                            } else {
                                installSpinner.succeed();
                                console.log(
                                    chalk.green("项目初始化完成,依赖已成功安装!")
                                );
                                console.log(
                                    chalk.white(
                                        `请执行以下命令启动项目\ncd ${name}\nnpm run start`
                                    )
                                );
                            }
                        }
                    );
                } else {
                    console.log(chalk.yellow("未找到package.json文件,无法安装依赖!"));
                }
            }
        })
    })
}
/**
 * @description 存在同名目录时,提示是否覆盖
 */
const handleExistDir = (name) => {
    inquirer.prompt([
        {
            type: "list",
            name: "cover",
            message: `当前目录下已存在 ${name} 目录,是否覆盖?`,
            choices: ["yes", "no"],
            filter: function (val) {
                return val.toLowerCase();
            },
        },
    ]).then(answers => {
        if (answers.cover === "yes") {
            // 删除已存在的同名目录
            const rimraf = require("rimraf");
            rimraf.sync(name);
            // 创建项目目录
            fs.mkdirSync(name);
            handleDownload(name);
        } else {
            console.log(chalk.red("项目初始化已取消,避免覆盖原有项目!"));
        }
    })
}
/**
 * @description 初始化项目
 */
const initCommand = (name) => {
    if (!name) {
        console.log(chalk.red("项目名称不能为空!"));
        return;
    }
    if (fs.existsSync(name)) {
        handleExistDir(name);
    } else {
        handleDownload(name);
    }
}
module.exports = initCommand;