摘要:命令行教程本文先介紹原生的實現命令行交互,了解原生的然后通過和實現一個完整的交互命令行工具。它是一個流也就是雙工流,除非指向一個文件,在這種情況下它是一個可讀流。命令行界面的完整解決方案,受啟發。
node 命令行教程
本文先介紹原生的node.js實現命令行交互,了解原生的api,然后通過commander.js和inquirer.js實現一個完整的交互命令行工具。
項目地址
process對象是一個全局變量,它提供了當前node.js進程的信息并對其控制。因為其是一個全局變量所以無需在文件中引入。
需要用到的幾個api
process.argv
process.cwd()
process.stdin
process.stdout
process.stdin.resume()
process.argvprocess.argv屬性返回一個數組。數組的第一個值是process.execPath,第二個是正在執行的JavaScript的文件路徑,其余參數為其它命令參數,這是我們來自定義命令的關鍵。
示例新建argv.js
// argv.js console.log(process.argv)
執行node命令 node argv.js
node argv.js --name zhu ## 輸出 [ "/usr/local/bin/node", ## 執行當前腳本的Node二進制文件的絕對路徑 "/Users/zhuhuilong/Node/Book/argv.js", ## 文件的絕對路徑 "--name", ## 其余參數 "zhu" ]
接收自定義的命令參數進行處理輸出
// argv.js console.log(process.argv) let argvs = process.argv let param = argvs.splice(2) if(param[0] && param[0] == "--name"){ if(param[1]){ console.log(`hello ${param[1]}`) }else{ console.log("請輸入name") } }
運行argv.js
node argv.js --name zhu ## 輸出 [ "/usr/local/bin/node", "/Users/zhuhuilong/Node/Book/argv.js", "--name", "zhu" ] hello zhu param [ "--name", "zhu" ]process.stdin與process.stdout
process.stdin(標準輸入)
process.stdin 屬性返回連接到 stdin (fd 0) 的流。 它是一個 net.Socket 流(也就是雙工流),除非 fd 0 指向一個文件,在這種情況下它是一個可讀流。
process.stdout(標準輸出)
process.stdout 屬性返回連接到 stdout (fd 1) 的流。 它是一個 net.Socket 流(也就是雙工流),除非 fd 1 指向一個文件,在這種情況下它是一個可寫流。
process.stdin.resume()一個指向 標準輸入流(stdin) 的可讀流(Readable Stream)。標準輸入流默認是暫停 (pause) 的,所以必須要調用 process.stdin.resume() 來恢復 (resume) 接收。
作為流,process.stdin可以在舊模式下使用。為了兼容node v0.10以前的版本。在舊模式喜愛使用stdin必須調用process.stdin.resume()。注意如果調用了process.stdin.resume() stdin將轉為舊模式。
通俗來講就是控制臺等待我們輸入內容不退出進程,對輸入輸出進行交互。
新建inputout.js
// inputout.js process.stdin.setEncoding("utf8") let argvs = process.argv let param = argvs.splice(2) if (param[0] && param[0] == "--name") { if (param[1]) { console.log(`hello ${param[1]}`) } else { process.stdout.write(`請輸入name:`) process.stdin.resume() process.stdin.on("data", chunk => { if (!!chunk.replace(/[ ]/g, "")) { process.stdout.write(`你輸入的name是: ${chunk}`) process.stdin.emit("end") } else { process.stdout.write(`請輸入name:`) } }) } } process.stdin.on("end", () => { process.stdout.write("結束 ") })
>執行node inputout.js --name
在新版本node模式下可以使用process.stdin.on("readable",()=>{})代替process.stdin.resume()恢復輸入流接收。
示例:
process.stdin.on("readable", () => { var chunk = process.stdin.read(); console.log(typeof(chunk)) if (chunk !==null) { process.stdout.write(`data: ${chunk}`); process.stdin.emit("end"); } }); process.stdin.on("end", () => { process.stdout.write("end"); });
從上面的示例我們可以拿到process.argv參數對其進行處理交互,但如果要實現更復雜的命令交互,使用上面的方法會很吃力。下面我們使用commander.js和inquirer來實現一個完整的node命令行工具(創建項目模版)。
commander.jsnode.js命令行界面的完整解決方案,受Ruby Commander啟發。
commander.js的API簡述program.version() 聲明版本
const program = require("commander") const pkg = require("../package.json") program.version(pkg.version)
Options 解析
使用.option()方法定義commander的選項options,也可以作為選項的文檔。
var program = require("commander"); program .version("0.1.0") .option("-p, --peppers", "Add peppers") .option("-P, --pineapple", "Add pineapple") .option("-b, --bbq-sauce", "Add bbq sauce") .option("-c, --cheese [type]", "Add the specified type of cheese [marble]", "marble") .parse(process.argv); console.log("you ordered a pizza with:"); if (program.peppers) console.log(" - peppers"); if (program.pineapple) console.log(" - pineapple"); if (program.bbqSauce) console.log(" - bbq"); console.log(" - %s cheese", program.cheese);
添加自定義命令program.command()
var program = require("commander"); program .command("rm") //<>必選參數,如果是[]則是可選參數 .option("-r, --recursive", "Remove recursively") .action(function (dir, cmd) { console.log("remove " + dir + (cmd.recursive ? " recursively" : "")) }) program.parse(process.argv) // command()可變參數 /** 命令command有且只有最后一個參數可變不固定的。 要使參數變量可變,必須將...附加到參數名稱。**/ program .version("0.1.0") .command("rmdir [otherDirs...]") .action(function (dir, otherDirs) { console.log("rmdir %s", dir); if (otherDirs) { otherDirs.forEach(function (oDir) { console.log("rmdir %s", oDir); }); } }); program.parse(process.argv);
program.action() 定義命令的回調函數
var program = require("commander"); program .command("rminquirer.js") .option("-r, --recursive", "Remove recursively") .option("-f, --force", "remove force") .action(function(dir, cmd) { // cmd為option參數選項 //console.log("cmd",cmd) if (cmd.recursive) { console.log("remove " + dir + " recursively"); } if (cmd.force) { console.log("remove " + dir + " forcefully"); } }); program.parse(process.argv);
Inquirer.js使用NodeJs做的一個通用交互式命令行用戶界面的集合。具有常用的控制臺交互操作。
由于交互的問題種類不同,inquirer為每個問題提供很多參數:
type:表示提問的類型,包括:input, confirm, list, rawlist, expand, checkbox, password, editor;
name: 存儲當前問題回答的變量;
message:問題的描述;
default:默認值;
choices:列表選項,在某些type下可用,并且包含一個分隔符(separator);
validate:對用戶的回答進行校驗;
filter:對用戶的回答進行過濾處理,返回處理后的值;
transformer:對用戶回答的顯示效果進行處理(如:修改回答的字體或背景顏色),但不會影響最終的答案的內容;
when:根據前面問題的回答,判斷當前問題是否需要被回答;
pageSize:修改某些type類型下的渲染行數;
prefix:修改message默認前綴;
suffix:修改message默認后綴。
創建cli.jsconst program = require("commander") const inquirer = require("inquirer") const fs = require("fs") const path = require("path") const pkg = require("../package.json") const CWD = process.cwd() const promptList = [ { type: "list", message: "請選擇一種模版", name: "template", choices: ["vue", "angular", "webpack-m-pages"], filter: function(val) { return val.toLowerCase() } } ] program .version(pkg.version) .command("create") .description("create project template") .action(function(dir, cmd) { const TEMPLATE_PATH = path.join(CWD, dir) if (fs.existsSync(TEMPLATE_PATH)) { } else { fs.mkdirSync(TEMPLATE_PATH) } if (dir) { inquirer.prompt(promptList).then(anwsers => { console.log(anwsers) }) } }) program.parse(process.argv)
運行 node cli/cli.js create vue
已經可以運行了,我們自定義一個命名替代每次都執行node
命令為:test-cli create
1、創建bin文件夾,在bin文件夾下創建index.js文件
#!/usr/bin/env node require("../cli/cli")
2、修改package.json文件
添加bin選項
"bin": { "test-cli": "./bin/index.js" },
3、執行npm link (如果沒有權限,執行sudo npm link)
4、測試
5、發布 npm publish (如果未登錄需先 npm login登錄)
6、發布完畢,需npm unlink解除本地的命令映射
npm install -g XXX
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109845.html
摘要:自阮大神的文章發布以來,有了一些改動,添加有很多有用的功能,特別是這個功能,對打造命令行工具集合非常有用,所以寫一個新版本的教程還是有必要的。 前言 使用命令行程序對程序員來說很常見,就算是前端工程師或者開發gui的,也需要使用命令行來編譯程序或者打包程序 熟練使用命令行工具能極大的提高開發效率,linux自帶的命令行工具都非常的有用,但是這些工具都是按照通用需求開發出來的,如果有一些...
摘要:標準方法參數存在在中更多詳情,可以參考官方鏈接。是一個包含命令行參數的數組。第一個元素是,第二個元素是文件的名稱。接下來的元素將是任何附加的命令行參數。時間年月日前端教程打印將會輸出以下結果時間年月日前端教程 標準方法參數存在在process.argv中 更多詳情,可以參考官方鏈接。 process.argv 是一個包含命令行參數的數組。第一個元素是node,第二個元素是JavaScr...
摘要:是一種設計用于關系型數據庫的查詢語言。另一方面,數據庫在最近十年變得相當流行。大多數數據庫都有驅動程序可以用,它們在上也有庫。我們已經完成了在中使用數據庫所必須知道的所有基礎知識。 本文轉載自:眾成翻譯譯者:網絡埋伏紀事鏈接:http://www.zcfy.cc/article/1751原文:https://blog.risingstack.com/node-js-database-t...
摘要:項目環境搭建教程針對開發工具等一下載和下載鏈接中文官網下載好之后使用命令行再次確認查看順便看看內置的版本如果是非安裝包形式,安裝的直接解壓的,不是程序安裝的形式,需要配置環境變量,必要時還需要配置要使用的版本出 ...
摘要:是將與以太坊交互的模塊。在路由器內部我需要我的以太坊地址,我將發送我的交易地址,合約地址和合約。你可以通過以太坊錢包或搜索合約。我們為以太坊創建了我們的一個極小的后端。 注意:在本教程中我使用web3js 1.0版本 大家好,我將解釋如何從NodeJS后端發送交易。我將使用rinkeby testnet并將創建一個路由器,還添加一些節點模塊并使用infura http接口來完成教程...
閱讀 954·2019-08-30 15:55
閱讀 551·2019-08-26 13:56
閱讀 2080·2019-08-26 12:23
閱讀 3295·2019-08-26 10:29
閱讀 600·2019-08-26 10:17
閱讀 2868·2019-08-23 16:53
閱讀 697·2019-08-23 15:55
閱讀 2814·2019-08-23 14:25