背景
在做 cli 工具的時候,非常需要命令行相關的第三方庫。一個比較穩健成熟的命令行應該考慮以下 4 種需求:
- 讀取傳入的各種參數,例如: --help, -v=123
- 邏輯處理和友好的 UI 交互,例如:提供列表選擇
- 細致控制字體顏色和背景顏色
- 狀態顯示,例如:等待過程前面是轉圈圈,完成過程前面自動換成對號
在開始前,安裝一下需要用到的庫:
npm install --save inquirer
npm install --save commander
npm install --save inquirer
npm install --save ora
下面的四個文件例子只需復制粘貼到文件通過node.js即可運行
讀取參數: commander
這里用到的是 commander 這個庫。它的文檔地址是:https://www.npmjs.com/package/commander
請先看下面代碼:
const program = require("commander");
// 分為2種操作, 2種操作互相沖突
// Options 操作
program
.version("0.0.1")
.option("-t, --types [type]", "test options")
// option這句話必須加
.parse(process.argv);
// Commands 操作
program
// 命令與參數: <> 必填; [] 選填
.command("exec <cmd> [env]")
// 別名
.alias("ex")
// 幫助信息
.description("execute the given remote cmd")
// 沒用,option和command是沖突的
.option("-e, --exec_mode <mode>", "Which exec mode to use")
// 執行的操作
.action((cmd, env, options) => {
// 參數可以拿到
console.log(`env is ${env}`);
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
})
// 自定義help信息
.on("--help", function() {
console.log("自定義help信息");
});
// 參數長度不夠, 打印幫助信息
if (!process.argv.slice(2).length) {
program.outputHelp();
}
if (program.types) {
console.log(program.types);
}
// 解析命令行參數
program.parse(process.argv);
文檔上基本都寫明白了,但是有幾個需要注意的點:
- 它主要提供 options 和 commands 兩種操作,option 就是形如“-t,--types”這樣的傳參,commands 就是形如“exec”這樣的傳參。 不要混用兩者 。
- 讀取 commands 中傳入的參數,寫在
.action
中;讀取 options 傳入的參數,是通過訪問program
上的變量。除此之外,options 操作需要執行 .parse(process.argv) 解析命令行參數 -V
和-h
默認也是提供的,但是也可以通過自定義覆蓋- 一般都把 options 寫在前面, 順便標識版本號 ;把 commands 寫在后面;最后會判斷一下參數長度,不夠會自動輸出打印信息
交互驗證:inquirer
深入交互並且提供基於命令行的選擇列表、彈框等 UI 視圖,我們借助:inquirer 庫。它的文檔地址是:https://www.npmjs.com/package/inquirer
請看下面這段代碼:
const inquirer = require("inquirer");
const program = require("commander");
program
.version("1.0.0")
.option("--sass [sass]", "啟用sass")
.option("--less", "啟用less")
.parse(process.argv);
program
.command("module [moduleName]")
.alias("m")
.description("創建新模塊")
.action(option => {
console.log(`option is ${option}`);
console.log(`program.sass is ${program.sass}`);
const config = {
moduleName: null,
des: "",
sass: false,
less: false
};
const promps = [];
// type: input
// 問答框類型
if (config.moduleName !== "string") {
promps.push({
type: "input",
name: "moduleName",
message: "請輸入模塊名稱",
validate: function(input) {
if (!input) {
return "輸入不能為空";
}
return true;
}
});
}
// type: list
// 列表選擇器類型
if (!program.sass && !program.less) {
promps.push({
type: "list",
name: "cssPretreatment",
message: "想用什么css預處理器呢",
choices: [
{
name: "Sass",
value: "sass"
},
{
name: "Less",
value: "less"
}
]
});
}
inquirer.prompt(promps).then(function(answers) {
console.log(answers);
});
});
program.parse(process.argv);
除去 commader 庫的應用,inquirer 庫的應用在 15~64 行。它首先會驗證是否傳入 module 參數,如果沒有,那么以問答的形式引導用戶輸入;緊接着檢查是否指定了 scss / less,如果沒有指定,彈出列表選擇器供用戶選擇。
整個過程中的交互體驗還是非常好的,尤其是針對多個選項的時候的列表選擇器,一目了然。
顏色控制:chalk
這個比較簡單,寫過 c 的同學應該知道控制命令行顏色,只需要 顏色宏定義 + 字體內容 拼接即可。所以這個庫也是,提供更語義化的 api 將文本處理成拼接后的結果,然后交給控制台輸出。
const chalk = require("chalk");
const print = console.log;
print(chalk.blue("Hello") + " World" + chalk.red("!"));
print(chalk.blue.bgRed.bold("Hello World!"));
過程控制:ora
它實現的核心功能是控制台刷新,我可以用它來做“下載進度條”(一直更新 text 屬性即可)。當然,項目中用它來做狀態提示,它會在語句前面給個轉圈圈的 icon,還會有對號、錯誤等終止狀態 icon。
看下面這段代碼,假想現在是在下載*。可以跑一下下面代碼,mac 下比 windows 下好太多**。
const ora = require("ora");
const spinner = ora({
text: "鏈接網絡中"
}).start(); // 開始狀態 => 加載狀態
setTimeout(() => {
spinner.color = "yellow";
spinner.text = "網速有點慢";
}, 1000); // 還是 加載狀態, 更新文案和顏色
setTimeout(() => {
spinner.succeed("下載成功"); // 加載狀態 => 成功狀態
}, 2000);
主要使用了 commander.js
&& inquirer.js
&& chalk.js
這三個庫。
推薦
阿里開發團隊一篇靠譜的文檔: 非常推薦
不推薦
commander.js文檔:看了后很多疑惑。。。