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

相关推荐
腾讯TNTWeb前端团队2 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰5 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪6 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪6 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy6 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom7 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom7 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom7 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom7 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom7 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试