Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

こんにちは、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」が便利だ
  • ラミちゃんの本名は「アレキサンダー・ラモン・ラミレス・キニョーネス」
0x50
コーダーです。インターフェイス周りのデザインや実装をやります。フロントエンドからサーバーサイドまで、色んな領域に足を突っ込んでは引き抜いてを繰り返しています。
http://p1ch.jp
dena_coltd
    Delight and Impact the World
https://dena.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした