Node.js理論實踐之《命令行工具》

平常開發中,遇到的各類命令行工具(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

image

可見,npm link建立了2個軟連接分別放到系統環境變量$PATH目錄裏,hello命令和hello-cli模塊。 npm link在用戶使用的場景下是不須要執行的,用戶使用npm i -g hello-cli命令安裝便可。git

此時再次執行 hello 時就不用輸入路徑了。github

hello
hello world
複製代碼

最後經過 npm publish發佈到npm官網,就能夠供你們安裝使用了。web

package.json

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' ]
複製代碼

除了上面原始方式以外,還有幾個比較流行的工具,好比yargscommander

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')

  • 第一個參數  自定義標誌<必須>:分爲長短標識,中間用逗號、豎線或者空格分割;標誌後面可跟參數,能夠用<> 或者 []修飾,前者意爲必須參數,後者意爲可選參數
  • 第二個參數  選項描述<省略不報錯>:在使用 --help 命令時顯示標誌描述
  • 第三個參數  選項參數默認值,可選。

除了option外,還有幾個經常使用的api:versioncommandparseoutputHelp。更多使用細節請參照其官方文檔。

其它依賴模塊

除了上述的yargscommander外,編寫命令行工具一般還會用到其它一些第三方模塊,好比:

  • inquirer: 命令行交互界面集合。能夠提問,解析輸入,校驗回答等
  • ora: 能夠使終端輸出更優雅,設置正在進行,成功或失敗
  • chalk: 能夠對終端輸出的文字設置一些顏色等樣式

有時還會用到download-git-repo,好比開發一個腳本架工具,在初始化項目時,須要實時地從github上拉取最新的項目模板。 這裏推薦一個智能合約的腳本架工具robin,有興趣的同窗能夠參考一下它的實現。

相關文章
相關標籤/搜索