本文介绍在实现 CLI 中常用的一些终端交互相关的四个工具包,如果你需要实现一个 CLI,这几个工具包必不可少。你只需要将他们组合一下,然后实现你的业务逻辑即可。
inquirer
https://github.com/SBoudrias/Inquirer.js
功能:用户和命令行交互(问卷),获取结果。
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
功能:在终端输出彩色文字。
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
功能:在终端中显示 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
功能:用于在终端中输出异步任务进度条,和常规的进度条不同的是,它会根据每个任务的历史记录来估算这个任务需要的时间。
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
可能有些人没听过,快用起来吧。