需要准备的工具
- 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("下载完成");
}
);
});
};