国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從零開始打造個人專屬命令行工具集——yargs完全指南

wanghui / 1849人閱讀

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

前言

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

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

minimist 源自

optimist 模仿python的optimist項目

commander.js tj是node.js大神,co的作者, commander.js源自ruby的commander項目,作者也是tj

nopt npm項目中使用

nomnom 不再維護,不建議使用

yargs

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

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

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

簡單模式

yargs默認使用兩個--作為參數(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ù)配置

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

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

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

#!/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)計verbose參數(shù)出現(xiàn)的次數(shù),縮寫-v也會統(tǒng)計進去,具體調(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ù)默認值
#!/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  [options]")
    .help("h")
    .alias("h", "help")
    .epilog("copyright 2015")
    .argv;
使用別名
var argv = require("yargs")
    .usage("Usage: $0  [options]")
    .alias("h", "help")
    .argv;

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

參數(shù)數(shù)組
var argv = require("yargs")
    .usage("Usage: $0  [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ù)組中的一個

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

子命令

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

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

.command

.command方法有三個接口

.command(cmd, desc, [builder], [handler])

.command(cmd, desc, [module])

.command(module)

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

使用第一個接口的示例

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

使用第三個接口需要把這個模塊在多帶帶的文件,然后用require引入

這是模塊的代碼

// my-module.js
exports.command = "get  [proxy]"

exports.describe = "make a get HTTP request"

exports.builder = {
  banana: {
    default: "cool"
  },
  batman: {
    default: "sad"
  }
}

exports.handler = function (argv) {
  // do something with argv.
}

引入的時候這樣使用

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

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

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

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

.commandDir

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

下面參考一個我自己寫的項目pit

下面是這個項目的目錄結(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

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

注意:commandDir默認只會加載目錄下第一級的文件,不會遞歸加載,如果想遞歸加載需要這樣寫.commandDir("pit", {recurse: true})

接著來看git子命令,因為git項目每次提交都要重復(fù)幾個相同的步驟,所有想開發(fā)一個更簡單的命令進行打包提交

git.js

exports.command = "git ";

exports.desc = "github command list";

exports.builder = function (yargs) {
  return yargs.commandDir("git")
}

exports.handler = function (argv) {}

git也是加載一個目錄作為自己的子命令:以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`);
    });

}

這個命令默認運行在git項目的根目錄,和git命令不太一樣,git可以在項目根目錄下的任意子目錄里面運行。

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

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

延伸

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

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

api命令行

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

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

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

命令行爬蟲

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

表單提交

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

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

歡迎大家交流自己的想法!

個人博客地址:自由前端

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/80042.html

相關(guān)文章

  • 用 Electron 打造 Win/Mac 應(yīng)用,從「代碼」到可下載的「安裝包」,可能比你想得麻煩一

    摘要:三配置環(huán)節(jié)目的一是為之后的環(huán)節(jié)初始化工作流參數(shù),二是準備好應(yīng)用文件夾內(nèi)容即要打包的目標(biāo)文件夾做的事解析命令行參數(shù),初始化工作參數(shù),填充配置文件,把配置文件和相關(guān)依賴文件導(dǎo)入到文件夾內(nèi)合適的 首發(fā)于酷家樂前端博客,作者@摘星(segmentfault @StinsonZhao) 我們能從很多地方學(xué)習(xí)到怎么起一個 Electron 項目,有些還會介紹怎么打包或構(gòu)建你的代碼,但距離「真正地...

    LdhAndroid 評論0 收藏0
  • 從零開始打造專屬釘釘機器人

    摘要:目前釘釘機器人支持方式,仍屬于內(nèi)側(cè)階段。方式是指被動接受通知,釘釘群中添加的群機器人默認都是該模式。截止撰寫文章時,釘釘?shù)臋C器人文檔不可訪問,所以會在下面介紹下。本文同步發(fā)表于作者博客從零開始打造專屬釘釘機器人 官方定義如下: 群機器人是釘釘群的高級擴展功能。群機器人可以將第三方服務(wù)的信息聚合到群聊中,實現(xiàn)自動化的信息同步。目前,大部分機器人在添加后,還需要進行Webhook配置,才可...

    fyber 評論0 收藏0
  • 前端之從零開始系列

    摘要:只有動手,你才能真的理解作者的構(gòu)思的巧妙只有動手,你才能真正掌握一門技術(shù)持續(xù)更新中項目地址求求求源碼系列跟一起學(xué)如何寫函數(shù)庫中高級前端面試手寫代碼無敵秘籍如何用不到行代碼寫一款屬于自己的類庫原理講解實現(xiàn)一個對象遵循規(guī)范實戰(zhàn)手摸手,帶你用擼 Do it yourself!!! 只有動手,你才能真的理解作者的構(gòu)思的巧妙 只有動手,你才能真正掌握一門技術(shù) 持續(xù)更新中…… 項目地址 https...

    Youngdze 評論0 收藏0

發(fā)表評論

0條評論

wanghui

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<