从 零 搭建 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 扩展库

相关推荐
HuangYongbiao20 分钟前
Rspack 原理:webpack,我为什么不要你
前端
yinuo24 分钟前
前端项目开发阶段崩溃?试试这招“Node 内存扩容术”,立马复活!
前端
前端鳄鱼崽26 分钟前
【react-native-inspector】全网唯一开源 react-native 点击组件跳转到编辑器
前端·react native·react.js
用户984022766791826 分钟前
【React.js】渐变环形进度条
前端·react.js·svg
90后的晨仔27 分钟前
Webpack完全指南:从零到一彻底掌握前端构建工具
前端·vue.js
Holin_浩霖28 分钟前
JavaScript 语言革命:ES6+ 现代编程范式深度解析与工程实践
前端
前端拿破轮33 分钟前
从0到1搭一个monorepo项目(一)
前端·javascript·git
m0_7414122438 分钟前
大文件上传与文件下载
前端
wu_jing_sheng039 分钟前
Python中使用HTTP 206状态码实现大文件下载的完整指南
开发语言·前端·python
90后的晨仔44 分钟前
Vue3项目全面部署指南:从构建到上线
前端·vue.js