平常開發中,遇到的各類命令行工具(cli), 如 vue init webpack xxx
, 不少是經過node.js開發的。node.js cli本質其實就是執行node腳本。javascript
首先使用JavaScript編寫一個可執行腳本 hellovue
#!/usr/bin/env node
console.log('hello world');
複製代碼
而後修改 hello文件的權限 $ chmod 755 hello
,此時就能夠執行 hello 了。java
$ ./hello
hello world
複製代碼
若是想把 hello 前面的路徑去除,須要將 hello 的路徑加入到環境變量 PATH。有一種更好的作法就是 使用 npm link
。 在當前目錄下新建 package.json ,寫入下面的內容。node
{
"name": "hello-cli",
"bin": {
"hello": "hello"
}
}
複製代碼
而後執行 npm link 命令,輸出 webpack
可見,npm link
建立了2個軟連接分別放到系統環境變量$PATH目錄裏,hello命令和hello-cli模塊。 npm link在用戶使用的場景下是不須要執行的,用戶使用npm i -g hello-cli命令安裝便可。git
此時再次執行 hello 時就不用輸入路徑了。github
hello
hello world
複製代碼
最後經過 npm publish
發佈到npm官網,就能夠供你們安裝使用了。web
scripts
指定了運行腳本命令的npm命令行縮寫,好比start指定了運行npm run start時,所要執行的命令。 下面的設置指定了npm run preinstall、npm run postinstall、npm run start、npm run test時,所要執行的命令。npm
"scripts": {
"preinstall": "echo here it comes!",
"postinstall": "echo there it goes!",
"start": "node index.js",
"test": "tap test/*.js"
}
複製代碼
bin
項用來指定各個內部命令對應的可執行文件的位置。json
"bin": {
"someTool": "./bin/someTool.js"
}
複製代碼
上面代碼指定,someTool 命令對應的可執行文件爲 bin 子目錄下的 someTool.js。Npm會尋找這個文件,在node_modules/.bin/目錄下創建符號連接。 在上面的例子中,someTool.js會創建符號連接node_modules/.bin/someTool。因爲node_modules/.bin/目錄會在運行時加入系統的PATH變量, 所以在運行npm時,就能夠不帶路徑,直接經過命令來調用這些腳本。
原生progress.argv
命令行參數能夠用系統變量 process.argv
獲取。
#!/usr/bin/env node
console.log('hello ', process.argv[2]);
複製代碼
執行時,直接在腳本文件後面,加上參數便可。
$ ./hello ben
hello ben
複製代碼
其中process爲node進程中的全局變量,process.argv爲一數組,數組內存儲着命令行的各個部分, argv[0]爲node的安裝路徑,argv[1]爲主模塊文件路徑,剩下爲子命令或參數,以下:
$ hello a b c
# process.argv的值爲[ '/usr/local/bin/node', '/Users/benyasin/Downloads/hello', 'a', 'b', 'c' ]
複製代碼
除了上面原始方式以外,還有幾個比較流行的工具,好比yargs
與commander
。
yargs
示例:
#!/usr/bin/env node
var argv = require('yargs')
.alias('n', 'name')
.argv;
console.log('hello ', argv.n);
複製代碼
能夠經過空格
或=
的方式進行賦值。還能夠使用alias指定別名。
$ hello -n tom
hello tom
$ hello --name tom
hello tom
$ hello --name=tom
hello tom
複製代碼
commander
#!/usr/bin/env node
const program = require('commander');
program
.option('-n, --name', 'your name', 'ben')
.parse(process.argv);
console.log('hello', program.name);
複製代碼
執行命令行程序的方式以下:
$ hello -n tom
hello tom
$ hello --name
hello ben
複製代碼
用法: .option('-n, --name <name>', 'description info', 'default value')
除了option
外,還有幾個經常使用的api:version
、command
、parse
、outputHelp
。更多使用細節請參照其官方文檔。
除了上述的yargs
或commander
外,編寫命令行工具一般還會用到其它一些第三方模塊,好比:
inquirer
: 命令行交互界面集合。能夠提問,解析輸入,校驗回答等ora
: 能夠使終端輸出更優雅,設置正在進行,成功或失敗chalk
: 能夠對終端輸出的文字設置一些顏色等樣式有時還會用到download-git-repo
,好比開發一個腳本架工具,在初始化項目時,須要實時地從github上拉取最新的項目模板。 這裏推薦一個智能合約的腳本架工具robin,有興趣的同窗能夠參考一下它的實現。