具体实现

    1#!/usr/bin/env node
    2
    3const inquirer = require("inquirer");
    4const { program } = require("commander");
    5const figlet = require("figlet");
    6const fs = require("fs-extra");
    7const path = require("path");
    8const chalk = require("chalk");
    9const gitClone = require("git-clone");
    10const ora = require("ora");
    11
    12const projectList = {
    13  vue: "git@gitee.com:codemydreams/blog-vitepress-template.git",
    14  react: "git@gitee.com:codemydreams/blog-vitepress-template.git",
    15  "vue&ts": "git@gitee.com:codemydreams/blog-vitepress-template.git",
    16  "react&ts": "git@gitee.com:codemydreams/blog-vitepress-template.git",
    17};
    18
    19// 修改帮助信息的首行提示
    20program.usage("<command> [options]");
    21
    22// 版本号
    23program.version(`v${require("../package.json").version}`);
    24
    25// 命令
    26program
    27  .command("create <app-name>")
    28  .description("创建一个新项目")
    29  .action(async function (appName) {
    30    // 创建项目的逻辑
    31    // 创建一个名字为appName的文件夹,把我们模版项目的代码都放到这个文件夹下面
    32    // 1.先判断有没有appName文件夹
    33    const targetPath = path.join(process.cwd(), appName);
    34    if (fs.existsSync(targetPath)) {
    35      // 存在的话
    36      const answer = await inquirer.prompt([
    37        {
    38          type: "confirm",
    39          name: "overwrite",
    40          default: false,
    41          message: "是否要覆盖之前的文件夹?",
    42        },
    43      ]);
    44      if (answer.overwrite) {
    45        fs.remove(targetPath);
    46      } else {
    47        return;
    48      }
    49    }
    50    // 2.新建
    51    const res = await inquirer.prompt([
    52      {
    53        type: "list",
    54        name: "type",
    55        message: "选择什么框架去新建项目?",
    56        choices: [
    57          {
    58            name: "Vue",
    59            value: "vue",
    60          },
    61          {
    62            name: "React",
    63            value: "react",
    64          },
    65        ],
    66      },
    67      {
    68        type: "list",
    69        name: "ts",
    70        message: "是否要用ts?",
    71        choices: [
    72          {
    73            name: "否",
    74            value: false,
    75          },
    76          {
    77            name: "是",
    78            value: true,
    79          },
    80        ],
    81      },
    82    ]);
    83    const key = res.type + (res.ts ? "&ts" : "");
    84    const spinner = ora(`Scaffolding project in ${targetPath}...`).start();
    85    gitClone(projectList[key], appName, { checkout: "master" }, function (err) {
    86      if (err) {
    87        spinner.fail("安装失败,请稍后重试");
    88      } else {
    89        // 删除.git文件夹,取消与远程仓库的关联
    90        fs.remove(path.join(targetPath, ".git"));
    91        spinner.succeed("安装成功!");
    92        console.log("\nDone. Now run:\n");
    93        console.log(chalk.green(`cd ${appName}`));
    94        console.log(chalk.green("npm install"));
    95        console.log(chalk.green("npm run dev\n"));
    96      }
    97    });
    98  });
    99
    100// 给help信息添加提示
    101program.on("--help", function () {
    102  console.log(
    103    `\n  Run ${chalk.blue(
    104      "vue <command> --help"
    105    )} for detailed usage of given command.`
    106  );
    107});
    108
    109program.parse(process.argv);