yargsでコマンドラインパーサーを実装する

nodejsのライブラリyargsを使っていくつかのパターンのコマンドラインのパースをしてみました。
2020.03.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

この記事ではtypescriptでちょっとしたコマンドラインツールを作った時に使ったyargsが便利だったので紹介したいと思います。

yargsとは

yargsはコマンドライン引数(コマンドや引数、オプション)をパースし、ヘルプメッセージなどを生成するライブラリです。

環境

今回使った環境は以下の通りです。

  • tsc: Version 1.5.3
  • node: v12.9.1

インストール

npm install -S yargs
npm install -D @types/yargs

基本的な使い方

yargsではいくつかの種類のコマンドライン引数をパースできます。順に使い方を見ていきます。

コマンド

コマンドはawscliのように引数として実行する処理内容などを指定するために用いられます。

awscliの引数は以下のようになっていて、例えば aws s3 ls s3://bucket/ とした場合のs3およびls がコマンドに当たります。

aws -h
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: the following arguments are required: command

以下の例ではhelloまたはbyeのどちらかのコマンドが必須となります。

import * as yargs from 'yargs'

const argv = yargs
  .command('hello', 'say hello')
  .command('bye', 'say bye')
  .demandCommand(1)
  .help()
  .argv

switch (argv._[0]) { 
  case 'hello':
    console.log('hello')
    break
  case 'bye':
    console.log('bye')
    break 
}

コマンドなしで実行した場合は(または—helpオプションをつけた場合)下記のようなメッセージが出力されます。

command.js <コマンド>

コマンド:
  command.js hello  say hello
  command.js bye    say bye

Options:
  --version  バージョンを表示                                             [真偽]
  --help     ヘルプを表示                                                 [真偽]

オプションではない引数が 0 個では不足しています。少なくとも 1 個の引数が必要です:

オプション

オプションはハイフン1つまたは2つに続いて指定される引数です。第2引数のオプションで必須かどうか、デフォルト値を設定できます。

import * as yargs from 'yargs'

const argv = yargs
  .option('name', {
    alias: 'n',
    description: 'ご芳名', 
    demandOption: true
  })
  .option('weapon', {
    alias: 'w',
    description: '武器',
    default: '銃'
  })
  .help()
  .argv

console.log(`こいよ! ${argv.name} !! ${argv.weapon}なんか捨ててかかっここい!`)

必須オプションの—nameを省略した場合は以下のようなメッセージが表示されます。

> node build/options.js 
Options:
  --version     バージョンを表示                                          [真偽]
  --name, -n    ご芳名                                           [文字列] [必須]
  --weapon, -w  武器                                 [文字列] [デフォルト: "銃"]
  --help        ヘルプを表示                                              [真偽]
必須の引数が見つかりません: name

オプションを指定した場合は以下のように入力値が使用されます。

> node build/options.js --name ベネット
こいよ! ベネット !! 銃なんか捨ててかかっここい!
> node build/options.js --name ベネット --weapon ナイフ
こいよ! ベネット !! ナイフなんか捨ててかかっここい!

ポジション引数

ポジション引数は処理の対象などを指定するためにcommandと一緒に使用します。

commandの第1引数の中に<> で囲んで位置と名前を指定します。

以下の例ではナデナデ(scritch)する鳥(birb)を指定しています。

import * as yargs from 'yargs'

const argv = yargs.command('scritch <birb>', 'scritch birbs', b => 
  b.positional('birb', {
    choices: ['conure', 'cockatiel'],
    demandOption: true
  })
)
.demandCommand(1)
.argv

console.log(`scritch, scritch ... ${argv.birb}`)

ヘルプメッセージは以下のようになります。

> node build/positional.js scritch 
positional.js scritch <birb>

scritch birbs

位置:
  birb                          [必須] [選択してください: "conure", "cockatiel"]

Options:
  --help     ヘルプを表示                                                 [真偽]
  --version  バージョンを表示                                             [真偽]

オプションではない引数が 0 個では不足しています。少なくとも 1 個の引数が必要です:

まとめ

コマンドライン引数をパースするライブラリは多くありますが、yargsは抜群に使いやすいと感じました。