玩轉 Nodejs 命令行


背景

在做 cli 工具的時候,非常需要命令行相關的第三方庫。一個比較穩健成熟的命令行應該考慮以下 4 種需求:

  1. 讀取傳入的各種參數,例如: --help, -v=123
  2. 邏輯處理和友好的 UI 交互,例如:提供列表選擇
  3. 細致控制字體顏色和背景顏色
  4. 狀態顯示,例如:等待過程前面是轉圈圈,完成過程前面自動換成對號

在開始前,安裝一下需要用到的庫:

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);

文檔上基本都寫明白了,但是有幾個需要注意的點:

  1. 它主要提供 options 和 commands 兩種操作,option 就是形如“-t,--types”這樣的傳參,commands 就是形如“exec”這樣的傳參。 不要混用兩者 。
  2. 讀取 commands 中傳入的參數,寫在 .action  中;讀取 options 傳入的參數,是通過訪問 program  上的變量。除此之外,options 操作需要執行  .parse(process.argv) 解析命令行參數
  3. -V  和 -h  默認也是提供的,但是也可以通過自定義覆蓋
  4. 一般都把 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文檔:看了后很多疑惑。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM