nodejs 编写脚手架

需要准备的工具

  • commander:提供了一种简单直接的方式来创建命令行接口,并处理命令行参数和选项
  • inquirer:一个强大的命令行交互工具,用于与用户交互和收集信息
  • ora:一个用于在命令行提供动画加载的库
  • download-git-repo: 用于下载git仓库的npm库

安装上面四个npm包

pakeage.json 中增加type和bin
{
  "name": "nodeDemo",
  "version": "1.0.0",
  "description": "",
  "type": "module",  // 使用import 导入的形式
  "bin": {
    "test-cli": "src/index.js"  // 自定义指令
  },
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.14",
    "@types/node": "^18.11.9"
  },
  "dependencies": {
    "axios": "^1.1.3",
    "commander": "^12.0.0",
    "download-git-repo": "^3.0.2",
    "express": "^4.18.2",
    "inquirer": "^9.2.19",
    "ora": "^8.0.1"
  }
}

建立src文件夹中写index.js 和 utils.js

index.js 代码

#!/usr/bin/env node
// 告诉系统我执行自定义命令, 你帮我用node执行

// 在pakeage.json 中创建bin命令,执行命令之前,先运行npm link 软连接,挂载到全局上

// program 可获取命令行后面的参数
import { program } from "commander";
// 使用fs 读取 pakeage.json 文件  获取当前的version版本号
import fs from "node:fs";
// 使用命令行交互工具
import inquirer from "inquirer";
// 注意需要导入的是utils.js 后缀不能忘记
import { checkPath, downloadTemp } from "./utils.js";

let json = fs.readFileSync("./package.json");
json = JSON.parse(json);

program.version(json.version);

// 创建一个目录
/**
 * create <projectName> 创建目录
 * alias 起别名
 * description 项目描述
 */
program
  .command("create <projectName>")
  .alias("yx")
  .description("自定义执行命令")
  .action((projectName) => {
    // console.log("projectName", projectName);
    // 使用命令行交互工具,进行互动
    inquirer
      .prompt([
        {
          type: "input", // 输入框
          name: "projectName",
          message: "请输入项目名称",
          default: projectName,
        },
        {
          type: "confirm", // 确认框
          name: "isTs",
          message: "是否支持TypeScript",
          default: projectName,
        },
      ])
      .then((res) => {
        if (checkPath(res.projectName)) {
          console.log("文件路径已存在");
          return;
        }
        if (res.isTs) {
          downloadTemp("ts", res.projectName);
        } else {
          downloadTemp("js", res.projectName);
        }
        console.log(res);
      });
  });

/**
 * process.argv 获取 命令行后面的参数 如 test-cli yx  可获取到 yx
 * program.parse 对参数进行处理
 */
program.parse(process.argv);

utils.js

import fs from "node:fs";

import download from "download-git-repo";

import ora from "ora";

const spinner = ora("下载中.....");

// 检查路径
export const checkPath = (path) => {
  return fs.existsSync(path);
};

/**
 *
 * @param {*} branch 分支名 是ts 还是js
 * @param {*} name 创建的目录名称
 * @returns
 */
export const downloadTemp = (branch, name) => {
  return new Promise((resolve, reject) => {
    spinner.start();
    download(
      `direct:https://gitee.com/chinafaker/vue-template.git#${branch}`,
      name,
      { clone: true },
      function (err) {
        if (err) reject(err);
        resolve();
        spinner.succeed("下载完成");
      }
    );
  });
};

上一篇:无人机在光伏电站巡检中的关键步骤与技巧


下一篇:Windows11+Ubuntu20.04系统重装(升级为Ubuntu22.04)