0、 命令行工具
當全局安裝模塊之后,我們可以在控制台下執行指定的命令來運行操作,如果npm一樣。我把這樣的模塊稱之為命令行工具模塊(如理解有偏頗,歡迎指正)
1、用Node編寫命令行工具
在Node中,我們很容易就能實現一個命令行工具。通過借助npm install -g安裝,就能直接調用命令行工具了。
1.1、創建項目
首先,命令行也是一個node程序,那么首先通過npm init初始化一個Node項目。
json // package.json { "name": "newkit-cli", "version": "0.0.1", "description": "Newkit Management Tools", "main": "index.js", "scripts": { "test": "test" }, "author": "Jay", "license": "MIT" }
1.2、創建可執行代碼
在項目目錄下,創建src目錄,並在其中創建index.js文件
javascript //src/index.js文件內容 console.log('cli');
通過node src/index
就可以執行到段代碼了,那如何用自定義命令來執行呢?
1.3、在package.json中配置自定義命令
在package.json中可以配置bin節點,當全局安裝的時候,該節點內容將會被注冊為自定義命令。 json { "name": "newkit-cli", "version": "0.0.1", "description": "Newkit Management Tools", "main": "index.js", "bin": { "nc": "./src/index.js" }, "scripts": { "test": "test" }, "author": "Jay", "license": "MIT" }
1.4、測試命令
假設我們已經寫好了命令行工具了,那我們應該如何測試呢?
我們可以通過npm install -g
將當前模塊安裝到全局模塊中。然后再執行nc命令來測試。
通過如上步驟,我們發現並不能執行我們的index.js,這是為什么呢?
因為我們並沒有指定用什么工具來執行這條命令,所以應該怎么做呢?打開index.js,然后加上一句代碼:
```javascript
!/usr/bin/env node
console.log('cli'); ``` 這句代碼什么意思呢?這句代碼告訴系統,使用node來啟動我們的命令。此時再安裝,然后執行nc,你會發現,控制台會打印出cli。也就是我們index中代碼的執行結果。
至此,我們的一個最簡單的命令行執行就開發成功了。
2、處理命令行參數
單純的執行一個命令,似乎不滿足我們的實際運用場景,大部分時候我們會使用nc version
、nc xxx -a --b
之類的方式來使用命令。那應該如何獲取這些命令呢?
2.1、使用process來獲取控制台參數
將index.js代碼修改一下,如下: ```javascript
!/usr/bin/env node
console.log('cli'); console.log(process.argv); ``` 安裝之后,再次執行nc xxx -a --b true
,會看到如下的輸出:
cli [ 'C:\\Program Files\\nodejs\\node.exe', 'C:\\Users\\jh3r\\AppData\\Roaming\\npm\\node_modules\\newkit-cli\\src\\index.js', 'xxx', '-a', '--b', 'true' ]
從結果可以看到,我們所使用所有參數都會傳遞到程序中去,這個時候,我們就可以解析這些參數,來實現不同的輸出了。
2.2、使用Commander來開發命令行工具
從上面的輸出也可以看到,我們要手動去解析參數的話,還是一個比較復雜的操作。既然身處Node社區,那么完全使用社區流行的包來幫我們簡化代碼。
Commander 是一款重量輕,表現力和強大的命令行框架。提供了用戶命令行輸入和參數解析強大功能。
Commander的方便之處在於:自記錄代碼、自動生成幫助、合並短參數(“ABC”==“-A-B-C”)、默認選項、強制選項、命令解析、提示符
我們可以在https://github.com/tj/commander.js/找到Commander。
繼續改造index.js文件,修改內容為: ```javascript
!/usr/bin/env node
var program = require('commander');
program .version('0.0.2') //提供命令行工具的版本號,可以通過-V獲取到 // 使用option方法注冊命令 .option('-i, --init [type]', 'Initial Newkit in current folder', (type) => { console.log('process', type, program.init); }, true) .option('-u| --update ', 'Update module.', (moduleName) => { //使用program.update 來獲取默認值,如果有命令行參數,那么會作為回調函數的參數 console.log(moduleName, program.update); }, 'app-common')
.parse(process.argv); ``` 注意:以上代碼有較多注意的點
- option方法參數是四個,第一個是命令,第二個是描述,第三個是回調,第四個是命令的默認值
- 第一個參數中的-i和-u是短命令,--init和--update是長命令。長短命令之間的分隔符可以是
|
和,
,如果使用逗號分隔,那么可以通過program.init來獲取默認值。 - 在代碼中我們在命令中,注意到有
[type]
和<module>
兩種,前者是可選參數,后者的必選參數。
除此之外,還可以使用command方法來實現Git風格的子命令,代碼如下:
javascript program .command('update <module>') .action((module, options) => { console.log(module); });
更多功能,請自行測試
2.3、使用yargs來開發命令行工具
具體代碼如下:
```javascript
!/usr/bin/env node
var argv = require('yargs') .option('i', { alias : 'init', demand: true, default: '', describe: 'Project Init', type: 'string' }) .usage('Usage: nc init') .example('nc init', 'Initial newkit project') .help('h') .alias('h', 'help') .epilog('copyright 2015') .argv;
//根據不同的參數來做處理
``` yargs更多信息請參閱:https://github.com/yargs/yargs
3、注意事項
- 根據Unix的傳統,程序執行成功返回0,否則返回1
javascript if(err){ return process.exit(1); } process.exit(0);
2. 系統信號
javascript process.on('SIGINT', function () { console.log('Got a SIGINT'); process.exit(0); }); //發送系統信號:$ kill -s SIGINT [process_id]