打造自己的CLI:(一)认识必备工具

301 阅读2分钟

1. chalk: 控制台输出内容样式美化

import chalk from 'chalk';

console.log(chalk.blue('Hello world!'));
  • 执行node index.js
  • 注意: 为了能直接使用import,需要在package.json 中加入 "type": "module"

2. bin相关

2-1、直接上手

  • 因为这是一个cli项目,为了随时测试cli的功能,需要再创建一个使用cli的demo。如使用 npm init -y创建一个my-cli-demo。
  • 然后在my-cli-demo中使用 npm link my-cli软链接到my-cli。
  • 但我想将cli链接到全局,需要在my-cli的package.json中添加
   "bin": {
    "mz": "bin/index.js"
  },
  • 在bin/index.js中写入
#! /usr/bin/env node
// 告诉系统直接在PATH目录中查找node命令

import chalk from 'chalk';

console.log(chalk.red('Hello BIN!!!'));
  • 然后再my-cli下 npm install . -g安装到全局
  • 在任意位置输入mz,都可以打印出Hello BIN!!!
  • 并且在my-cli-demo的node_modules中会生成一个bin文件,bin下面会有个mz

2-2、bin的用途

  • 开发者可能会将自定义的脚本或工具放在bin文件夹中,以便在项目构建、部署或维护过程中使用。这些脚本可能是node脚本,用于执行特定的任务或自动化流程。

2-3、推荐阅读的其他资料

3. commander: 命令行解决方案

  • git地址: github.com/tj/commande…
  • commander 可以帮助我们规范的处理用户的命令,比如 mz -v获取版本号,mz init -t project用来创建项目
import { Command } from 'commander';

 const program = new Command();
 
 program
        .name('mz')
        .version(packageInfo.version, '-v, --version', 'output the current version!');

 
    program
        .command('init')
        .description('创建模板')
        .option('-t, --type <type>', `模板类型。
            project: 新建项目
            component: 新建组件模板
            module: 新建模块模板
        `,(value) => {
            const validValues = ['project', 'component', 'module']
            if (!validValues.includes(value)) {
                showError(`Invalid value: ${value}`)
                showTips('mz init -h for help')
                process.exit(1)
            }
            return value
        })
        .action(async (params, options) => {
            await init(params, options)
        })
        
        program.parse();   

image.png

  • 其中,command('init') 定义了名为init的命令,也就是当我们输入init时才会触发后面的处理方法,description描述,option 选项,action就是命令触发时的处理函数,第一个参数是用户传入的参数 (type: project),第二个参数是当前command对象。
  • program.parse() 开始执行
  • process.argv 中的process是node中的全局变量,argv是启动命令行时的所有参数。
  • program.parse(process.argv) 是将命令行参数传递给commander开始执行。

4 inquirer.js

image.png

image.png

  • 以上效果可以使用inquirer实现,先npm install inquirer
import inquirer from 'inquirer'
export async function project() {
    const res = await inquirer.prompt([
        {
            type: 'rawlist',
            message: '请选择',
            name: 'selected',
            choices: [
                {
                    name: '张三',
                    value: 'zs'
                },
                {
                    name: '李四',
                    value: 'ls'
                }
            ]
        }
    ])
}
  • type 指定交互类型,rawlist-单选列表,input输入,checkbox多选等。
  • message就是提示语。