自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Node交互式命令行工具開發(fā)——自動(dòng)化文檔工具

開發(fā) 開發(fā)工具 自動(dòng)化
nodejs開發(fā)命令行工具,流程相對(duì)簡(jiǎn)單,但一套完整的命令行程序開發(fā)流程下來(lái),還是需要下點(diǎn)功夫,網(wǎng)上資料大多零散,這篇教程意在整合一下完整的開發(fā)流程。

[[390895]]

nodejs開發(fā)命令行工具,流程相對(duì)簡(jiǎn)單,但一套完整的命令行程序開發(fā)流程下來(lái),還是需要下點(diǎn)功夫,網(wǎng)上資料大多零散,這篇教程意在整合一下完整的開發(fā)流程。

npm上命令行開發(fā)相關(guān)包很多,例如minimist、optimist、nopt、commander.js、yargs等等,使用方法和效果類似。其中用得比較多的是TJ大神的commander和yargs,本文以commander為基礎(chǔ)講述,可以參考這篇教程,yargs教程可以參考阮大神的或者這一篇。

另外,一個(gè)完整的命令行工具開發(fā),還需要了解process、shelljs、path、linebyline等模塊,這些都是node基礎(chǔ)模塊或一些簡(jiǎn)單模塊,非常簡(jiǎn)單,就不多說(shuō)了,另外如果你不想用回調(diào)函數(shù)處理異步還需要了解一下Promise、Generator函數(shù)。這是教程:i5ting大神的《深入淺出js(Node.js)異步流程控制》和阮大神的異步編程教程以及promise小人書,另外想嘗試ES7 stage3階段的async/await異步解決方案,可參考這篇教程,async/await解決方案需要babel轉(zhuǎn)碼,這是教程。本人喜歡async/await(哪個(gè)node開發(fā)者不喜歡呢?)但不喜歡倒騰,況且async/await本身就是Promise的語(yǔ)法糖,所以沒(méi)選擇使用,據(jù)江湖消息,nodejs將在今年晚些時(shí)候(10月份?)支持async/await,很是期待。

以下是文章末尾實(shí)例用到的一些依賴。 

  1. "dependencies": {  
  2.     "bluebird": "^3.4.1",  
  3.     "co": "^4.6.0",  
  4.     "colors": "^1.1.2",  
  5.     "commander": "^2.9.0",  
  6.     "dox": "^0.9.0",  
  7.     "handlebars": "^4.0.5",  
  8.     "linebyline": "^1.3.0",  
  9.     "mkdirp": "^0.5.1"  
  10.   } 

其中bluebird用于Promise化,TJ大神的co用于執(zhí)行Generator函數(shù),handlebars是一種模板,linebyline用于分行讀取文件,colors用于美化輸出,mkdirp用于創(chuàng)建目錄,另外教程中的示例是一款工具,可以自動(dòng)化生成數(shù)據(jù)庫(kù)和API接口的markdown文檔,并通過(guò)修改git hooks,使項(xiàng)目的每次commit都會(huì)自動(dòng)更新文檔,借助了TJ大神的dox模塊。

<span style="color:rgb(0, 136, 204)">所有推薦教程/教材,僅供參考,自行甄選閱讀。</span>

安裝Node

各操作系統(tǒng)下安裝見Nodejs官網(wǎng),安裝完成之后用node -v或者which node等命令測(cè)試安裝是否成功。which在命令行開發(fā)中是一個(gè)非常有用的命令,使用which命令確保你的系統(tǒng)中不存在名字相同的命令行工具,例如which commandName,例如which testdev命令返回空白那么說(shuō)明testdev命令名稱還沒(méi)有被使用。

初始化

新建一個(gè).js文件,即是你的命令要執(zhí)行的主程序入口文件,例如testdev.js。在文件第一行加入#!/usr/bin/env node指明系統(tǒng)在運(yùn)行這個(gè)文件的時(shí)候使用node作為解釋器,等價(jià)于node testdev.js命令。

初始化package.json文件,使用npm init命令根據(jù)提示信息創(chuàng)建,也可以是使用npm init -y使用默認(rèn)設(shè)置創(chuàng)建。創(chuàng)建完成之后需要修改package.json文件內(nèi)容加入"bin": {"testdev": "./testdev.js"}這條信息用于告訴npm你的命令(testdev)要執(zhí)行的腳本文件的路徑和名字,這里我們指定testdev命令的執(zhí)行文件為當(dāng)前目錄下的testdev.js文件。

為了方便測(cè)試在testdev.js文件中加入代碼console.log('hello world');,這里只是用于測(cè)試環(huán)境是否搭建成功,更加復(fù)雜的程序邏輯和過(guò)程需要按照實(shí)際情況進(jìn)行編寫

測(cè)試

使用npm link命令,可以在本地安裝剛剛創(chuàng)建的包,然后就可以用testdev來(lái)運(yùn)行命令了,如果正常的話在控制臺(tái)會(huì)打印出hello world

commander

TJ的commander非常簡(jiǎn)潔,README.md已經(jīng)把使用方法寫的非常清晰。下面是例子中的代碼: 

  1. const program = require('commander'),  
  2.   co = require('co');  
  3. const appInfo = require('./../package.json'),  
  4.   asyncFunc = require('./../common/asyncfunc.js');  
  5. program.allowUnknownOption();  
  6. program.version(appInfo.version);  
  7. program  
  8.   .command('init')  
  9.   .description('初始化當(dāng)前目錄doc.json文件')  
  10.   .action(() => co(asyncFunc.initAction));  
  11. program  
  12.   .command('show')  
  13.   .description('顯示配置文件狀態(tài)')  
  14.   .action(() => co(asyncFunc.showAction));  
  15. program  
  16.   .command('run')  
  17.   .description('啟動(dòng)程序')  
  18.   .action(() => co(asyncFunc.runAction));  
  19. program  
  20.   .command('modifyhook')  
  21.   .description('修改項(xiàng)目下的hook文件')  
  22.   .action(() => co(asyncFunc.modifyhookAction));  
  23. program  
  24.   .command('*')  
  25.   .action((env) => {  
  26.     console.error('不存在命令 "%s"', env);  
  27.   });  
  28. program.on('--help', () => {  
  29.   console.log('  Examples:');  
  30.   console.log('');  
  31.   console.log('    $ createDOC --help');  
  32.   console.log('    $ createDOC -h');  
  33.   console.log('    $ createDOC show');  
  34.   console.log('');  
  35. });  
  36. program.parse(process.argv); 

定義了四個(gè)命令和個(gè)性化幫助說(shuō)明。

交互式命令行process

commander只是實(shí)現(xiàn)了命令行參數(shù)與回復(fù)一對(duì)一的固定功能,也就是一個(gè)命令必然對(duì)應(yīng)一個(gè)回復(fù),那如何實(shí)現(xiàn)人機(jī)交互式的命令行呢,類似npm init或者eslint --init這樣的與用戶交互,交互之后根據(jù)用戶的不同需求反饋不同的結(jié)果呢。這里就需要node內(nèi)置的process模塊。

這是我實(shí)現(xiàn)的一個(gè)init命令功能代碼: 

  1. exports.initAction = function* () {  
  2.   try {  
  3.     var docPath = yield exists(process.cwd() + '/doc.json');  
  4.     if (docPath) {  
  5.       func.initRepl(config.coverInit, arr => {  
  6.         co(newDoc(arr));  
  7.       })  
  8.     } else {  
  9.       func.initRepl(config.newInit, arr => {  
  10.         co(newDoc(arr));  
  11.       })  
  12.     }  
  13.   } catch (err) {  
  14.     console.warn(err);  
  15.   } 

首先檢查doc.json文件是否存在,如果存在執(zhí)行覆蓋交互,如果不存在執(zhí)行生成交互,try...catch捕獲錯(cuò)誤。

交互內(nèi)容配置如下:   

  1. newInit:  
  2.     [  
  3.         {  
  4.             title:'initConfirm',  
  5.             description:'初始化createDOC,生成doc.json.確認(rèn)?(y/n)  ',  
  6.             defaults: 'y'  
  7.         },  
  8.         {  
  9.             title:'defaultConfirm',  
  10.             description:'是否使用默認(rèn)配置.(y/n)  ',  
  11.             defaults: 'y'  
  12.         },  
  13.         {  
  14.             title:'showConfig',  
  15.             description:'是否顯示doc.json當(dāng)前配置?(y/n)  ',  
  16.             defaults: 'y'  
  17.         }  
  18.     ],  
  19.     coverInit:[  
  20.         {  
  21.             title:'modifyConfirm',  
  22.             description:'doc.json已存在,初始化將覆蓋文件.確認(rèn)?(y/n)  ',  
  23.             defaults: 'y' 
  24.         },  
  25.         {  
  26.             title:'defaultConfirm',  
  27.             description:'是否使用默認(rèn)配置.(y/n)  ',  
  28.             defaults: 'y'  
  29.         },  
  30.         {  
  31.             title:'showConfig',  
  32.             description:'是否顯示doc.json當(dāng)前配置?(y/n)  ',  
  33.             defaults: 'y'  
  34.         }  
  35.     ], 

人機(jī)交互部分代碼也就是initRepl函數(shù)內(nèi)容如下: 

  1. //初始化命令,人機(jī)交互控制  
  2. exports.initRepl = function (init, func) {  
  3.   var i = 1 
  4.   var inputArr = [];  
  5.   var len = init.length;  
  6.   process.stdout.write(init[0].description);  
  7.   process.stdin.resume();  
  8.   process.stdin.setEncoding('utf-8');  
  9.   process.stdin.on('data', (chunk) => {  
  10.     chunkchunk = chunk.replace(/[\s\n]/, '');  
  11.     if (chunk !== 'y' && chunk !== 'Y' && chunk !== 'n' && chunk !== 'N') {  
  12.       console.log(config.colors.red('您輸入的命令是: ' + chunk));  
  13.       console.warn(config.colors.red('請(qǐng)輸入正確指令:y/n'));  
  14.       process.exit();  
  15.     }  
  16.     if (  
  17.       (init[i - 1].title === 'modifyConfirm' || init[i - 1].title === 'initConfirm') &&  
  18.       (chunk === 'n' || chunk === 'N')  
  19.     ) {  
  20.       process.exit();  
  21.     }  
  22.     var inputJson = {  
  23.       title: init[i - 1].title,  
  24.       value: chunk,  
  25.     };  
  26.     inputArr.push(inputJson);  
  27.     if ((len--) > 1) {  
  28.       process.stdout.write(init[i++].description)  
  29.     } else { 
  30.       process.stdin.pause();  
  31.       func(inputArr);  
  32.     }  
  33.   });  

人機(jī)交互才用向用戶提問(wèn)根據(jù)用戶不同輸入產(chǎn)生不同結(jié)果的形式進(jìn)行,順序讀取提問(wèn)列表并記錄用戶輸入結(jié)果,如果用戶輸入n/N則終止交互,用戶輸入非法字符(除y/Y/n/N以外)提示輸入命令錯(cuò)誤。

文檔自動(dòng)化

文檔自動(dòng)化,其中數(shù)據(jù)庫(kù)文檔自動(dòng)化,才用依賴sequelize的方法手寫(根據(jù)需求不同自行編寫邏輯),API文檔才用TJ的dox也很簡(jiǎn)單。由于此處代碼與命令行功能相關(guān)度不大,請(qǐng)讀者自行去示例地址查看代碼。 

 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2019-01-03 09:06:55

Node.js命令行工具 前端

2024-04-26 09:44:39

2021-09-09 16:45:07

HTTP命令Linux

2019-06-10 15:00:27

node命令行前端

2020-12-10 16:16:08

工具代碼開發(fā)

2020-12-11 06:44:16

命令行工具開發(fā)

2018-05-04 09:15:35

PythonPlumbum命令行

2023-06-09 07:45:29

Kuberneteskubectl

2018-05-08 08:35:34

LinuxDocker 容器管理器

2015-10-14 17:59:53

Google數(shù)據(jù)探索交互開發(fā)

2021-02-02 10:15:55

工具命令行Node

2011-01-18 19:11:26

Postfix命令行

2010-11-24 17:12:17

MySQL命令行

2013-12-09 14:29:13

OpenStack命令行工具API

2023-10-30 01:00:42

Go語(yǔ)言Cobra庫(kù)

2011-05-30 17:50:23

分布式測(cè)試

2011-05-31 18:17:07

分布式測(cè)試

2010-12-09 21:46:26

Scapy

2013-05-21 14:58:08

系統(tǒng)監(jiān)視glances開源

2010-06-07 14:45:37

Linux下載工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)