實戰 | 從零開始使用JavaScript製做本身的命令行(CLI工具)

1_R0mii3Di1F2ZCFSx1JJDPg.jpeg

咱們天天都使用CLI程序(例如Terminal,cmd,Powershell等)進行軟件開發。你使用的每一個工具本質上都是其餘軟件工程師的產品,咱們也能夠製做本身的CLI工具。javascript

從零開始的簡單CLI,讓咱們開始吧!前端

首先,讓咱們製做一個簡單的CLI工具,該工具會打印「 HelloWord」

要製做CLI,您須要製做兩個文件java

  • package.json:將設置和配置指定入口
  • index.js:根據CLI命令的可執行文件

添加Package.json 文件node

// package.json
{
  "name": "my-cli",
  "version": "0.0.1",
  "description": "nodejs cli program",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Dunizb",
  "license": "ISC"
}

在package.json中,指定有關當前CLI程序的元數據, nameversiondescriptionauthor等。web

建立 index.js 可執行文件面試

// index.js
#! /usr/bin/env node
console.log('Hello CLI');

那麼,第一句話是什麼意思?shell

Linux和基於Unix的操做系統(例如Mac)中,#! / usr / bin / env node 不單單是一個註釋。它使用在 /usr/bin/env 中註冊的node命令來運行文件。npm

可是,在Windows中,這只是一個註釋。json

添加bin屬性segmentfault

咱們添加 bin 屬性來實際運行 index.js 文件

// package.json
{
  "name": "my-cli",
  "version": "0.0.1",
  ...
  ...
  "license": "ISC",
  "bin": {
    "cli": "./index.js"
  }
}

bin 屬性具備可執行文件,cli 命令要求運行 index.js 文件。

運行CLI

最後,讓咱們運行CLI在控制檯上打印Hello CLI。經過運行 npm i -g 在package.json中安裝配置。

下次你在控制檯上運行 npm i -g,您得到了 updated 1 package...,而不是 added 1 package ...

而後運行 cli 命令。終於, Hello CLI!

你可能須要在Mac和Linux環境中附加 sudo 命令(即 sudo cli),沒有 node_modules 文件夾,由於你沒有安裝依賴項。

CLI中的Process.argv

// index.js
#! /usr/bin/env node
console.log('Hello CLI', process.argv);

你可使用 process.argv 在命令中找到選項,選項以數組形式顯示。

你不須要在每次更新 index.js 代碼時再次運行 npm i -g,由於你已經將 package.jsonbin 屬性鏈接到 cli 命令和 index.js 文件。所以,每次調用 cli 命令時,均可以執行 index.js 文件(它不是來自緩存的,所以您能夠運行新的更新內容)。

在終端中運行命令:

cli one two three four

結果

數組中的前兩個元素nodecli 命令的路徑。(對於Windows系統,它可能會打印出不一樣的輸出)輸出可能會因您的計算機設置和環境而異(這取決於您在計算機上安裝nodecli命令的位置)。

此外,one two three four 表示爲數組類型

其次,經過「用戶輸入」與用戶交互的簡單CLI工具

使用稱爲readline的本機Node模塊從用戶那裏獲取輸入。

// index.js
#! /usr/bin/env node
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.question("你今天好嗎(快樂, 悲傷)?", (answer) => {
  if(answer === "快樂") {
    console.log("聽你這麼說我很高興");
  } else if (answer === "悲傷") {
    console.log("但願你明天感受好些")
  } else {
    console.log("你是快樂仍是悲傷?");
  }
    rl.close();
});

你可使用 readline 模塊中的 createInterface 方法建立 rl 對象。

process.stdinprocess.stdout 是控制檯輸入和輸出流。

readline 模塊接受來自用戶的輸入,rl 對象提問法是向用戶提問的一種方法,回調函數具備一個 answer 參數(來自用戶的輸入),若是全部 I/O(輸入和輸出)完成,則關閉 rl 對象。

咱們是否能夠經過再次詢問用戶在這種狀況下是否既不回答「高興」也不回答「悲傷」來進一步提升CLI ?

再次詢問用戶時,是否回答錯誤

#! /usr/bin/env node
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

console.clear();

const answerCallback = (answer) => {
  if (answer === "快樂") {
    console.log("聽你這麼說我很高興");
    rl.close();
  } else if (answer === "悲傷") {
    console.log("但願你明天感受好些");
    rl.close();
  } else {
    console.log("你是快樂仍是悲傷?");
    rl.question("你今天好嗎(快樂,悲傷)? ", answerCallback);
  }
};

rl.question("你今天好嗎(快樂,悲傷)?", answerCallback);

當程序開始使用 console. Clear 時清除控制檯,而後使用 rl.question 方法詢問用戶輸入並使用answerCallback 函數得到答案。

若是答案既不是悲傷也不是快樂,請清除控制檯,而後遞歸再次提問,若是答案是悲傷或快樂,關閉輸入控制檯。

最後

在本文中,咱們練習了一種製做簡單的CLI工具(要求用戶輸入)的方法。但願你喜歡閱讀。

更多的高級和實用的例子能夠從博客上找到進階版CLI。


文章首發《前端外文精選》微信公衆號

subscribe2.png

繼續閱讀其餘高贊文章


相關文章
相關標籤/搜索