溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

npm模塊中yargs有什么用

發(fā)布時(shí)間:2021-11-15 17:00:38 來源:億速云 閱讀:136 作者:小新 欄目:系統(tǒng)運(yùn)維

小編給大家分享一下npm模塊中yargs有什么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

前言

使用命令行程序?qū)Τ绦騿T來說很常見,就算是前端工程師或者開發(fā)gui的,也需要使用命令行來編譯程序或者打包程序

熟練使用命令行工具能極大的提高開發(fā)效率,linux自帶的命令行工具都非常的有用,但是這些工具都是按照通用需求開發(fā)出來的  ,如果有一些特別的需求,還是需要自己寫腳本來完成一些比如文件批量重命名,文件內(nèi)容批量替換等任務(wù)來提供工作效率。

在node.js出來之前,python經(jīng)常被用來開發(fā)一些腳本完成特殊的任務(wù),比如python爬蟲,python相關(guān)的教程有很多,有興趣的自己google。

得益于node.js的異步io特性,使用node開發(fā)io密集類任務(wù)變得非常簡單,這篇文章就為大家講講怎么使用node.js的yargs模塊來開發(fā)自己的命令行工具集合。

命令行參數(shù)解析

yargs是一個(gè)npm模塊用來完成命令行參數(shù)解析的,回到使用shell開發(fā)命令行的時(shí)代,getopts是***代命令行參數(shù)解析工具,經(jīng)過shell  => python => node.js  的迭代,命令行參數(shù)解析程序其實(shí)沒有多大的進(jìn)化,它們的目的始終是把用戶從命令行傳入的參數(shù)解析成指定的格式,供程序使用

雖然沒有多大變化,但是由于開發(fā)一個(gè)命令行參數(shù)解析模塊比較簡單,所以目前node社區(qū)存在很多類似yargs的開源項(xiàng)目,這里簡單列舉一下,有興趣的可以自己去了解一下,  然后選擇自己喜歡的項(xiàng)目來使用。

  • minimist 源自

  • optimist 模仿python的optimist項(xiàng)目

  • commander.js tj是node.js大神,co的作者, commander.js源自ruby的commander項(xiàng)目,作者也是tj

  • nopt npm項(xiàng)目中使用

  • nomnom 不再維護(hù),不建議使用

yargs

讀過阮一峰的Node.js 命令行程序開發(fā)教程之后開始使用yargs開發(fā)自己命令行工具, 用過一段時(shí)間發(fā)現(xiàn)非常的好用。

自阮大神的文章發(fā)布以來,yargs有了一些改動(dòng),添加有很多有用的功能,特別是.commandDir(directory,  [opts])這個(gè)功能,對打造命令行工具集合非常有用,所以寫一個(gè)新版本的yargs教程還是有必要的。

yargs的用法還算比較簡單,對英文有自信的可以去首頁閱讀原版:yargs

簡單模式

yargs默認(rèn)使用兩個(gè)--作為參數(shù)的前綴,中間使用空格或者=都可以

下面的代碼展示了yargs最簡單的用法,你只需要引入yargs,就能讀取命令行參數(shù),不需要寫任何的配置,非常的簡單

#!/usr/bin/env node var argv = require('yargs').argv;  if (argv.ships > 3 && argv.distance < 53.5) {     console.log('Plunder more riffiwobbles!'); } else {     console.log('Retreat from the xupptumblers!'); }
$ ./plunder.js --ships=4 --distance=22 Plunder more riffiwobbles!  $ ./plunder.js --ships 12 --distance 98.7 Retreat from the xupptumblers!

示例代碼都來自官網(wǎng):yargs

簡單模式還能讀取短變量如-x 4相當(dāng)于argv.x = 4

簡單模式還能讀取布爾類型-s相當(dāng)于argv.s = true

簡單模式還能讀取非-開始的變量,這種類型的變量保存在argv._數(shù)組里面

參數(shù)配置

簡單模式的功能都只用一行代碼就能實(shí)現(xiàn)

var argv = require('yargs').argv;

但是如果你想統(tǒng)計(jì)變量出現(xiàn)的次數(shù)怎么辦? 答案就是添加參數(shù)配置選項(xiàng)。

#!/usr/bin/env node var argv = require('yargs')     .count('verbose')     .alias('v', 'verbose')     .argv;  VERBOSE_LEVEL = argv.verbose;  function WARN()  { VERBOSE_LEVEL >= 0 && console.log.apply(console, arguments); } function INFO()  { VERBOSE_LEVEL >= 1 && console.log.apply(console, arguments); } function DEBUG() { VERBOSE_LEVEL >= 2 && console.log.apply(console, arguments); }  WARN("Showing only important stuff"); INFO("Showing semi-important stuff too"); DEBUG("Extra chatty mode");

上面的程序能統(tǒng)計(jì)verbose參數(shù)出現(xiàn)的次數(shù),縮寫-v也會(huì)統(tǒng)計(jì)進(jìn)去,具體調(diào)用例子參考下面的代碼

$ node count.js Showing only important stuff  $ node count.js -v Showing only important stuff Showing semi-important stuff too  $ node count.js -vv Showing only important stuff Showing semi-important stuff too Extra chatty mode  $ node count.js -v --verbose Showing only important stuff Showing semi-important stuff too Extra chatty mode

yargs提供很多接口用來幫助完善命令行程序,

提示用法

var argv = require('yargs')     .usage('Usage: $0 -w [num] -h [num]')     .argv;

必選參數(shù)

#!/usr/bin/env node var argv = require('yargs')     .usage('Usage: $0 -w [num] -h [num]')     .demand(['w','h'])     .argv;

 提供參數(shù)默認(rèn)值

#!/usr/bin/env node var argv = require('yargs')     .default('x', 10)     .default('y', 10)     .argv ; console.log(argv.x + argv.y);

打印幫助信息

#!/usr/bin/env node var argv = require('yargs')     .usage('Usage: $0 <command> [options]')     .help('h')     .alias('h', 'help')     .epilog('copyright 2015')     .argv;

使用別名

var argv = require('yargs')     .usage('Usage: $0 <command> [options]')     .alias('h', 'help')     .argv;

訪問argv.h相當(dāng)于訪問argv.help

參數(shù)數(shù)組

var argv = require('yargs')     .usage('Usage: $0 <command> [options]')     .alias('n', 'name')     .array('n')     .argv;  console.log(argv.n);

 調(diào)用

node array_test.js -n abc test

設(shè)置參數(shù)范圍

var argv = require('yargs')   .alias('i', 'ingredient')   .describe('i', 'choose your sandwich ingredients')   .choices('i', ['peanut-butter', 'jelly', 'banana', 'pickles'])   .help('help')   .argv

上述代碼設(shè)定argv.i的值只能是['peanut-butter', 'jelly', 'banana', 'pickles']數(shù)組中的一個(gè)

上面是yargs比較簡單的用法,如果想閱讀完整版,建議去github上閱讀

子命令

yargs適合開發(fā)復(fù)雜的命令行程序的另一個(gè)原因是它支持子命令,而且子命令可以嵌套,這意味著你也可以開發(fā)出類似git這樣擁有上百個(gè)命令的程序

yargs的子命令有兩種模式:.command(*)和.commandDir(directory, [opts])

.command

.command方法有三個(gè)接口  .command(cmd, desc, [builder], [handler])  .command(cmd, desc, [module])  .command(module)

其實(shí)它們的用法都差不多,可以把它們都看作傳遞一個(gè)module給yargs,這個(gè)module必須導(dǎo)出四個(gè)變量cmd, desc [builder],  [handler],其中builder和handler是方法,另外兩個(gè)是字符串

使用***個(gè)接口的示例

yargs   .command(     'get',     'make a get HTTP request',     function (yargs) {       return yargs.option('u', {         alias: 'url',         describe: 'the URL to make an HTTP request to'       })     },     function (argv) {       console.log(argv.url)     }   )   .help()   .argv

使用第三個(gè)接口需要把這個(gè)模塊在單獨(dú)的文件,然后用require引入

這是模塊的代碼

// my-module.js exports.command = 'get <source> [proxy]'  exports.describe = 'make a get HTTP request'  exports.builder = {   banana: {     default: 'cool'   },   batman: {     default: 'sad'   } }  exports.handler = function (argv) {   // do something with argv. }

引入的時(shí)候這樣使用

yargs.command(require('my-module'))   .help()   .argv

當(dāng)額外的模塊沒有定義cmd和desc的時(shí)候可以使用第二個(gè)接口

yargs.command('get <source> [proxy]', 'make a get HTTP request', require('my-module'))   .help()   .argv

這里建議使用第三個(gè)接口,這樣能保持模塊的內(nèi)聚,這種模塊你能掛載在任何命令下面,遷移的時(shí)候不需要修改模塊代碼,只需要修改引入模塊的代碼就能實(shí)現(xiàn)

.commandDir

如果有大量的命令都使用上面的.command(module)來開發(fā)的話,這些模塊都有相同的結(jié)構(gòu),應(yīng)該能有方法簡化這些命令的引入過程,把這個(gè)過程自動(dòng)化,基于  這個(gè)目的yargs提供了.commandDir接口

下面參考一個(gè)我自己寫的項(xiàng)目pit

下面是這個(gè)項(xiàng)目的目錄結(jié)構(gòu)

.  ├── pit  │ ├── douban  │ │ └── movie.js  │ ├── douban.js  │ ├── gg  │ │ ├── client.js  │ │ ├── login.js  │ │ ├── scope.js  │ │ ├── scope.json  │ │ ├── secret.json  │ │ ├── token.json  │ │ └── upload.js  │ ├── gg.js  │ ├── git  │ │ ├── commit.js  │ │ ├── create.js  │ │ ├── deploy.js  │ │ ├── push.js  │ │ └── token.json  │ ├── git.js  │ ├── gm.js  │ ├── md5.js  │ ├── news  │ │ ├── bing.js  │ │ ├── funs.js  │ │ ├── funs.json  │ │ ├── games.js  │ │ ├── games.json  │ │ ├── google.js  │ │ ├── newsall.json  │ │ ├── shops.js  │ │ ├── shops.json  │ │ ├── videos.js  │ │ └── videos.json  │ └── news.js  └── pit.js

pit.js:命令行的入口

#!/usr/bin/env node  require('yargs')   .commandDir('pit')   .demand(1)   .help()   .locale('en')   .showHelpOnFail(true, 'Specify --help for available options')   .argv &middot;&middot;&middot;

這段代碼只指定讀取同目錄下同名文件夾`pit`下面的命令加載為子命令

> **注意**:commandDir默認(rèn)只會(huì)加載目錄下***級的文件,不會(huì)遞歸加載,如果想遞歸加載需要這樣寫`.commandDir('pit',  {recurse: true})`

接著來看git子命令,因?yàn)間it項(xiàng)目每次提交都要重復(fù)幾個(gè)相同的步驟,所有想開發(fā)一個(gè)更簡單的命令進(jìn)行打包提交

git.js

exports.command = 'git ';  exports.desc = 'github command list';  exports.builder = function (yargs) { return yargs.commandDir('git') }  exports.handler = function (argv) {}

git也是加載一個(gè)目錄作為自己的子命令:以commit為例

commit.js

'use strict';  var fs = require('fs'); var path = require('path');  require('shelljs/global');  var Q = require('q');  function _exec(cmd) { var deferred = Q.defer(); exec(cmd, function (code, stdout, stderr) { deferred.resolve(); }); return deferred.promise; }  exports.command = 'commit';  exports.desc = 'commit repo local';  exports.builder = function (yargs) { return yargs .help('h'); };  exports.handler = function (argv) { var repo = process.cwd(); var name = path.basename(repo); Q.fcall(function () { }) .then(() => _exec(git add .)) .then(() => _exec(git commit -m 'd')) .catch(function (err) { console.log(err); }) .done(() => { console.log(commit ${repo} done); });  } ```

這個(gè)命令默認(rèn)運(yùn)行在git項(xiàng)目的根目錄,和git命令不太一樣,git可以在項(xiàng)目根目錄下的任意子目錄里面運(yùn)行。

使用shelljs來運(yùn)行子命令,然后用Q進(jìn)行promise封裝,保證命令的執(zhí)行順序,同時(shí)把命令行輸出和錯(cuò)誤信息都打印到 控制。

一個(gè)很簡單能節(jié)省時(shí)間的命令行程序,作為拋磚引玉之用

延伸

高手都是擅長使用命令行(電影里面的高手也一樣),當(dāng)你習(xí)慣使用命令行完成日常任務(wù)之后,慢慢的會(huì)形成一種依賴。繼續(xù)下去,你會(huì)考慮把所有的事情都用來命令行來完成,當(dāng)然這個(gè)  目的不能實(shí)現(xiàn),因?yàn)槟茏詣?dòng)完成所有任務(wù)的命令行不叫命令行&mdash;&mdash;它叫AI

雖然不能開發(fā)一臺(tái)高智能ai,但是還是有很多任務(wù)能用命令行來完成的,這里寫下我的思路,供大家參考

api命令行

大型網(wǎng)站都提供自己的api接口配上oauth3.0認(rèn)證,如果你想使用命令行來調(diào)用這些api接口,你完全可以做到

像aws,google cloud,aliyun這種云主機(jī),使用命令行能節(jié)省很多運(yùn)維的時(shí)間

另外你也可以參考上面pit.js寫的douban.js來抓取豆瓣的數(shù)據(jù),豆瓣的公共api不需要認(rèn)證就能訪問,用來做一些測試非常方便

命令行爬蟲

使用node.js開發(fā)爬蟲就像使用python一樣簡單,但是一個(gè)功能齊全的爬蟲必然少不了命令行接口,你不可能每次有新的需求都來修改代碼,下次再給大家分享我寫的一個(gè)簡單的基于  node.js的爬蟲項(xiàng)目

表單提交

對一些不提供api接口但是又想使用命令來進(jìn)行交互的網(wǎng)站,你可以使用表單提交來進(jìn)行登錄,然后做一些登錄之后才能做的事情:例如發(fā)表文章

現(xiàn)在很多的網(wǎng)站都支持使用markdown編輯文章,然后發(fā)布,對這一類網(wǎng)站你都可以開發(fā)自己的命令行統(tǒng)一進(jìn)行管理,當(dāng)你寫完文章之后,只需要一個(gè)簡單  的命令,就能把文章同時(shí)推送到各大網(wǎng)站

以上是“npm模塊中yargs有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI