39
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DeNA IPプラットフォーム事業部Advent Calendar 2017

Day 18

Node.jsでサクッとCLIアプリ作るなら cacjs が便利だよ

Posted at

こんにちは、Pちゃんです。
この記事は、DeNA IPプラットフォーム事業部 Advent Calendar 2017 18日目の記事です。
@koooootake に勧誘されて、うっかりアドベントカレンダーに登録してしまいました。


さて、今日はNode.jsを使ってサクッとCUIアプリケーションを作る方法を紹介していきたいと思います。

技術選定

一見、CLIアプリケーションの一つや二つくらい、素のNode.jsでも書くことができそうだと考えがちです。
しかし、サブコマンドの処理やオプションの処理、ヘルプを出すことなどを考えると、意外と面倒だったりします。
そこで、何かしらのフレームワークに乗っかるのが合理的です。

Node.jsでCUIアプリケーションをつくるためのフレームワークは、わりと数年前からデファクトが決まっています。
自分の観測範囲では、以下の2つがよく使われている気がします。

しかし、今回は敢えて cacjs を紹介しようと思います。
cacjs は、@egoist がつくった、シンプルでパワフルなコマンドラインインターフェイスをつくるためのフレームワークです。

特徴としては、

  • 一つのコマンドに関する処理を一箇所にまとめて書けるので、直感的に書きやすい
  • プラグイン機構を備えているため、本気でカスタマイズしていくことも可能である

などがあります。

cacjs でCLIアプリをつくる

1. cacjs をインストールする

$ mkdir cli-app-sample && cd cli-app-sample
$ npm init
$ npm install cac

2. コードを書く

index.js をつくって、以下を書きます。
以下、敬称略です。

index.js
const cac = require('cac')
const cli = cac()

const managers = ['ラミレス', '中畑', '尾花', '大矢', '牛島']

cli.command('managers', {
  desc: '横浜DeNAベイスターズの今の監督を表示します'
}, () => {
  console.log(`今の監督は${managers[0]}です`)
})

cli.parse()

3. 実行してみる

実はもうさっき書いた十数行でCLIアプリができています。
試しに managers を実行してみます。

$ node index.js managers
今の監督はラミレスです

次に --help とかも試してみます。

$ node index.js --help

  index.js 1.0.0

  USAGE

    index.js <command> [options]

  COMMANDS

    managers  横浜DeNAベイスターズの今の監督を表示します

  GLOBAL OPTIONS

    -v, --version  Display version                     [Type: boolean]
    -h, --help     Display help (You're already here)  [Type: boolean]

$ node index.js --version
1.0.0

すげえ、簡単すぎる。

4. サブコマンドを試してみる

先ほどのサンプルを改造して、過去の監督も取得できるようにしてみたいと思います。
cli.command のコールバックで input が返ってくるので、それを利用します。

index.js
const cac = require('cac')

const cli = cac()

const managers = ['ラミレス', '中畑', '尾花', '大矢', '牛島']

cli.command('managers', {
  desc: '横浜DeNAベイスターズの過去の監督を表示します'
}, (input) => {
  if (input[0] > 0) {
    console.log(`${input[0]}人前の監督は${managers[input[0]]}です`)
  } else {
    console.log(`今の監督は${managers[0]}です`)
  }
})

cli.parse()
$ node index.js managers 1
1人前の監督は中畑です

5. フラグを試してみる

さて、先ほどのサンプルをさらに改造して、監督のフルネームも取得できるようにしてみようと思います。
今回の場合、$ node index.js managers 3 --fullname などとすると、3人前の監督がフルネームで取得できるようにします。
cli.command のコールバックで flag が返ってくるので、それを利用します。

index.js
const cac = require('cac')

const cli = cac()

const managers = [
  ['アレックス', 'ラミレス'],
  ['中畑', ''],
  ['尾花', '高夫'],
  ['大矢', '明彦'],
  ['牛島', '和彦']
]

cli.command('managers', {
  desc: '横浜DeNAベイスターズの過去の監督を表示します'
}, (input, flag) => {

  let managerNum = input[0] || 0

  if (managerNum > managers.length - 1 ) {
    console.log(`${managers.length}人以上前の監督のデータはありません...`)
    process.exit(1)
  }

  let managerName = managers[managerNum][0]

  // ここで flag.fullname を見て true ならフルネームにする
  if (flag.fullname) {
    managerName += ' ' + managers[managerNum][1]
  }

  if (!managerNum) {
    console.log(`今の監督は${managerName}です`)
  } else if (managers.length > managerNum) {
    console.log(`${managerNum}人前の監督は${managerName}です`)
  }
})

cli.parse()
$ node index.js managers 4 --fullname
4人前の監督は牛島 和彦です

まとめ

  • Node.jsで、サクッとCLIアプリ作るなら「cacjs」が便利だ
  • ラミちゃんの本名は「アレキサンダー・ラモン・ラミレス・キニョーネス」
39
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?