实现 CLI 常用工具包 - 终端交互相关(问卷、彩色文字、loading、进度条)

360次阅读  |  发布于3年以前

本文介绍在实现 CLI 中常用的一些终端交互相关的四个工具包,如果你需要实现一个 CLI,这几个工具包必不可少。你只需要将他们组合一下,然后实现你的业务逻辑即可。

inquirer

https://github.com/SBoudrias/Inquirer.js[1]

功能:用户和命令行交互(问卷),获取结果。

Demo

代码

const inquirer = require('inquirer');
const chalk = require('chalk');

inquirer
  .prompt([
    {
      type: 'input',
      name: 'name',
      message: '请输入你的姓名',
    },
    {
      type: 'list',
      name: 'sex',
      message: '请选择你的性别',
      choices: ['男', '女'],
    },
    {
      type: 'checkbox',
      name: 'like',
      message: '请选择你的爱好',
      choices: ['写代码', '打游戏', '打篮球', '逛抖音'],
    },
  ])
  .then(answers => {
    const { name, sex, like } = answers;
    console.log('---- 个人信息 ----');
    console.log(chalk.green('姓名: '), name);
    console.log(chalk.green('性别: '), sex);
    console.log(chalk.green('爱好: '), like.join(', '));
  });

chalk

https://github.com/chalk/chalk[2]

功能:在终端输出彩色文字。

Demo

代码

一般在实际 CLI 实现中,我们会封装一个 log 工具函数,导出 success / error / warning 等方法,在不同实际去执行,分别输出绿色、红色、黄色的信息,代码大致如下:

// 封装
const chalk = require('chalk');

const success = msg => {
  console.log(chalk.green(`✔ ${msg}`));
};

const error = msg => {
  console.log(chalk.red(`× ${msg}`));
};

const warning = msg => {
  console.log(chalk.yellow(`⚠️ ${msg}`));
};

module.exports = {
 success,
  warning,
  error
};

// 使用
const log = require('./log');

log.success('成功!!!');
log.warning('警告!!!');
log.error('失败!!!');

ora

https://github.com/sindresorhus/ora[3]

功能:在终端中显示 loading 动画图标。

Demo

代码

一般在实际 CLI 实现中,会封装一个 spinner 工具函数,导出 start / stop / success / error 等方法,在业务逻辑中调用异步方法是就可以使用 spinner loading 等待。

// 封装
const ora = require('ora');
const chalk = require('chalk');

const spinner = ora();

const start = msg => {
  spinner.text = chalk.blue(msg);
  spinner.start();
};

const success = msg => {
  spinner.stopAndPersist({
    symbol: chalk.green('✔'),
    text: chalk.green(msg),
  });
};

const stop = () => {
  spinner.stop();
};

const error = msg => {
  spinner.fail(chalk.red(msg));
};

module.exports = {
  start,
  stop,
  success,
  error,
};

// 使用
const spinner from './spinner';

spinner.start('Loading...');

setTimeout(() => {
  spinner.success('Load success');
}, 2000);

progress-estimator

https://github.com/bvaughn/progress-estimator[4]

功能:用于在终端中输出异步任务进度条,和常规的进度条不同的是,它会根据每个任务的历史记录来估算这个任务需要的时间。

Demo

第一次:无历史记录

第二次:有 1 次历史记录

第三次:有 2 次历史记录

可以看到每次 estimated 后面的时间都不一样,这对于用户体验来说是比较友好的,能够较为准确地告知用户此次异步操作需要多少时间。比如一次下载模板的网络请求,用户需要了解自己这一次请求还需要多久。

代码

const createLogger = require('progress-estimator');
const chalk = require('chalk');
const path = require('path');

let _logger = null;
const logger = (task, message, estimate) => {
  if (!_logger) {
    _logger = createLogger({
      storagePath: path.join(__dirname, '.progress-estimator'),
    });
  }
  return _logger(task, chalk.blue(message), {
    estimate,
  });
};

const task1 = new Promise(resolve => {
  setTimeout(() => {
    resolve({ success: true });
  }, 1200);
});

const task2 = new Promise(resolve => {
  setTimeout(() => {
    resolve({ success: true });
  }, 4200);
});

async function run() {
  const startTime = Date.now();
  console.log();
  console.log(chalk.blue('Some Tasks'));
  console.log();
  await logger(task1, 'Task 1', 1500);
  await logger(task2, 'Task 2', 600);
  const endTime = Date.now();
  const time = ((endTime - startTime) / 1000).toFixed(2);
  console.log();
  console.log(chalk.green(`✨ Done in ${time}s`));
  console.log();
}

run();

总结

就是这么简单, inquirer / chalk / ora 比较常见, progress-estimator 可能有些人没听过,快用起来吧。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8