从 零 搭建 CLI

前言

记得刚毕业那会,新开项目,脚手架都是在老项目上直接拷贝,再删除多余的业务代码,费时费力,且不好维护,扩展性差。稍不留神,还留下多余的东西,后人接手,难以维护治理。这时,就要拿出 CLI,来定制符合自己业务的功能的 CLI

使用到的库

commander 定义命令行指令

inquirer 交互

chalk 美化命令输出

实现简单CLI

1. 初始化项目,生成package.json

bash 复制代码
     pnpm init && pnpm add commander inquirer chalk
json 复制代码
{
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "chalk": "^5.3.0",
    "commander": "^11.0.0",
    "inquirer": "^9.2.11"
  }
}

2. 根目录创建index.mjs

js 复制代码
#! /usr/bin/env node
console.log('我是自定义指令');

#! /usr/bin/env node 作用是告诉电脑用 【node】 执行文件

3. 修改 package.json 注册命令(test)

json 复制代码
{
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "bin": {
    "test": "index.mjs"
  },
  "dependencies": {
    "chalk": "^5.3.0",
    "commander": "^11.0.0",
    "inquirer": "^9.2.11"
  }
}

ps: 项目要使用ESModule,得配置 type 为 【module】

4. 使用 npm link,并输入test,控制台将输出 【我是自定义指令】

bash 复制代码
 npm link  & test

效果如下

commander

上面实现了最简单的CLI命令,如果要实现例如 vue create xxx 的能力,我们就要借用 【commander】

1. 修改 index.mjs

js 复制代码
#! /usr/bin/env node

import fs from 'node:fs';
import path from 'node:path';

import chalk from 'chalk';

import { Command } from "commander";

const program = new Command();

program
    .command('create <文件名字> [文件后缀(默认.js)]') // 指定名字和参数
    .description('创建文件') // 注释 test -h
    .action((filename, filesuffix = 'js') => {
        // create 命令逻辑
        // chalk 美化 console.log 输出文案

        const pathUrl = path.resolve(process.cwd(), `${filename}.${filesuffix}`);
        const content = '// 我是注释' + new Date().getSeconds()
        if (fs.existsSync(pathUrl)) {
            // 文件存在
            console.log(chalk.red('要创建的文件名已存在'))
        } else {
            fs.appendFileSync(pathUrl, content, { encoding: 'utf-8' })
        }
        console.log(chalk.green(filename, filesuffix));
    })

program.parse(process.argv)

2. 使用test create 创建 index.js

将会在当前路径下得到index.js 文件

bash 复制代码
test create index

效果如下

inquirer

上面借用【commander】, 实现了简单的create功能,接下用【inquirer】,实现复杂的命令行交换能力

1. 修改 index.mjs

js 复制代码
#! /usr/bin/env node

import fs from 'node:fs';
import path from 'node:path';

import chalk from 'chalk';

import { Command } from "commander";
import inquirer from 'inquirer';

const program = new Command();

program
    .command('createPKG') // 指定名字和参数
    .description('创建package.json 文件') // 注释 test -h
    .action(() => {
        const pathUrl = path.resolve(process.cwd(), 'package.json');
        if (fs.existsSync(pathUrl)) {
            console.log(chalk.red('package.json文件已存在'))
        } else {
            inquirer
                .prompt([
                    {
                        name: 'name',
                        type: 'input',
                        message: '项目名称'
                    },
                    {
                        name: 'version',
                        type: 'input',
                        message: '版本号',
                        default: '1.0.0' // 默认值
                    },
                    {
                        name: 'description',
                        type: 'input',
                        message: '项目的描述'
                    }
                ]) // 录入问题
                .then((answers) => {
                    console.log(answers);
                    fs.appendFileSync(pathUrl, JSON.stringify(answers), { encoding: 'utf-8' })
                })

        }
    })


program.parse(process.argv)

2. test createPKG 创建 package.json 文件

bash 复制代码
test createPKG

效果如下

总结

日常工作或者学习中,可以通过CLI,集成自己的工具, 减少一些重复的工作,提高效率。

ora 用于loading
fs-extra fs 扩展库

相关推荐
EricWang13589 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning9 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人19 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
超雄代码狂41 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程1 小时前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
Justinc.2 小时前
CSS3新增边框属性(五)
前端·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js