打造一个属于自己的cli,新手向

311 阅读3分钟

背景

由于自己做的项目越来越多,除了公司项目还有一些自己练(wai)手(bao)的项目,我发现了一个痛点,就是每次我都需要自己搭建项目,虽然可以用官方提供的cli,也很方便,但这样只会让自己成为码农,不能一边赚钱一边进步,而且如果有版本更新了也需要熟悉去看,那不如自己从头搭建一个!

需求分析

其实我自己写了很多项目了,配置过很多脚手架,正常的流程是

打开github -> 挑选模板 -> git clone -> 本地开发

这样其实很麻烦,要知道github是经常打不开的(狗头),而且点开网站点来点去也很麻烦

所以需要一个cli,流程就变成

npm install cli -> 选择模板 -> git clone -> 本地开发

这样!就很方便!一个命令行工具就搞定!

开始开发

首先要新建一个项目,用来存放cli的代码

npm init

新建一个package.json,并添加bin字段,bin 字段是命令名到本地文件名的映射。在安装时,npm 会将文件符号链接到 prefix/bin 以进行全局安装或./node_modules/.bin/本地安装。(如果安装了没用可能是环境变量没配好)

{
  "name": "ikun-cli",
  "version": "1.0.4",
  "description": "ikun专属工具",
  "main": "index.js",
  "bin": {
    "ikun": "bin/ikun.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "chalk": "^4.0.1",
    "clear": "^0.1.0",
    "figlet": "^1.5.2",
    "git-pull-or-clone": "^2.0.1",
    "inquirer": "^8.2.2"
  }
}

由于功能比较简单,这里主要用到几个包

chalk 一个命令提示符的工具,主要显示一些标题,输出特殊颜色字体,用来区分

clear 清理命令行工具

figlet 设置字体

git-pull-or-clone 拉取仓库代码用的

inquirer 用户与命令行交互的工具

然后就是书写bin的指令内容

#!/usr/bin/env node
//上面这行很重要 告诉系统可以在PATH目录中查找

const { promisify } = require("util");
const figlet = promisify(require("figlet"));
const clear = require("clear");
const inquirer = require("inquirer");
const package = require('../package.json')
const { log } = require("../lib/api"); 

const opt = {
  "下载vue-ssr": 'vue-ssr',
  "当前版本": 'version',
  "退出": "quit",
};

const question = [
  {
    type: "rawlist" /* 选择框 */,
    message: "请选择要执行的操作?",
    name: "operation",
    choices: Object.keys(opt),
  }
];

clear();

log(
  figlet.textSync("IKUN!", {
    horizontalLayout: "Isometric1",
    verticalLayout: "default",
    width: 80,
    whitespaceBreak: true,
  }), 'blue'
)

query();

async function query(){
  const answer = await inquirer.prompt(question);
  console.log("answer", answer);
  if (answer.operation === "退出") return;
  if (answer.operation === "当前版本"){
    log(`当前版本号:${package.version}`)
    return
  }
  await require(`../lib/${opt[answer.operation]}`)();
  return
}

lib目录对应的是执行的命令,这里我先放了一个我两年前写的一个SSR的Vue脚手架,自己可以把对应地址改掉,就可以自己使用了

//lib/api.js
const chalk = require("chalk");
 
 module.exports.log = (msg, color='green', ...arg) => console.log(chalk[color](msg, arg));
 
 //手续放入一下公共方法
// lib/vue-ssr.js
const { promisify } = require("util");
const download = promisify(require("git-pull-or-clone"));
const ora = require("ora");
const inquirer = require("inquirer");
const { resolve } = require("path");
const { log } = require("./api");



module.exports = async () => {
  console.log("path", resolve("."));
  // 项⽬名称
  const name = await inquirer.prompt([{
    type: 'input',
    message: '设置文件名',
    name: 'name',
    default: "vue-serve" // 默认值
  }])
  const repo = 'https://gitee.com/11111231/serveCli.git'
  const path = resolve(`./${name.name}`);
  console.log("path", path);
  const process = ora(`下载中.....${repo}`);
  process.start();
  try {
    await download(repo, path);
    process.succeed();
    log(`下载完成`);
  } catch (e) {
    console.log(e);
    process.fail();
  }
};

发布到npm

没用账号的同学自行注册一下

首先登陆npm

为啥出现这个问题 image.png 原来是使用了淘宝镜像

npm set registry=registry.npmjs.org/

解决

npm login

image.png

npm publish

image.png

这样一个属于你的cli就存放在npm了

yarn global add ikun-cli

下载到本地

执行 ikun

image.png

Window用户记得配置一下环境变量(由此引申多平台应该如何解决)

image.png

保存!执行!

ikun

image.png

好家伙!

原来是我下的node版本问题,用的17.8.0,官方稳定版本16.14.2

更换版本!

ikun

image.png

至此一个简单的属于自己的cli就可以了