Node.jsでCLIツールを作ろう!〜Commanderを使ったコマンド実装パターン〜

2024/05/25に公開

はじめに

Node.jsを使ってCLIツールを開発する際に便利なのが、Commanderライブラリです。Commanderを使うと、コマンドラインからの入力を簡単に解析し、適切なアクションを実行することができます。
今回は、Commanderを使ったコマンド実装のパターンを紹介します。このパターンに従うことで、CLIツールに新しいコマンドを追加するのが容易になります。

プロジェクトの構成

プロジェクトのディレクトリ構成は以下のようになります。

src/
  ├── commands/
  │   ├── server.ts
  │   └── ・・・
  └── index.ts

src/commands/: 各コマンドの実装を格納するディレクトリ
src/index.ts: コマンドを登録し、CLIツールのエントリーポイントとなるファイル

コマンドの実装

まずは、src/commands/server.tsを作成し、serveコマンドを実装します。

server.ts
import { Command } from 'commander';

export const serveCommand = new Command()
  .command('serve')
  .description('Open a file for editing')
  .action(() => {
    console.log('Getting ready to serve a file!');
  });

Commandをインポートし、新しいコマンドインスタンスを作成
.command('serve')で、コマンド名を指定
.description('Open a file for editing')で、コマンドの説明を追加
.action(() => { ... })で、コマンドが実行された際のアクションを定義

コマンドの登録

次に、src/index.tsを編集し、作成したコマンドを登録します。

index
import { program } from 'commander';
import { serveCommand } from './commands/server';

program.addCommand(serveCommand);

program.parse(process.argv);

Commanderからprogramをインポート
作成したserveCommandをインポート
program.addCommand(serveCommand)で、serveCommandを登録
program.parse(process.argv)で、コマンドラインの引数を解析

型定義ファイルのインストール

TypeScriptを使用している場合、Node.jsの型定義ファイルをインストールする必要があります。

bash
lerna add @types/node --dev --scope=cli

lerna addを使って、@types/nodeをインストール
--devフラグを付けて、開発依存関係として追加
--scope=cliで、cliパッケージにのみインストール

CLIツールの実行

コンパイル後、生成されたdist/index.jsを実行することで、CLIツールを試すことができます。

bash
node packages/dist/index.js serve

serveコマンドを実行すると、Getting ready to serve a file!というメッセージが表示されます。
また、--helpオプションを付けて実行すると、利用可能なコマンドとその説明が表示されます。

bash
node packages/dist/index.js --help

おわりに

以上が、Commanderを使ったコマンド実装のパターンです。このパターンに従うことで、CLIツールに新しいコマンドを追加するのが容易になります。
今回は基本的な実装のみを紹介しましたが、実際のCLIツールではもっと複雑な処理が必要になることもあるでしょう。しかし、このパターンを理解していれば、それらの処理を適切な場所に追加していくことができます。
ぜひ、自分のCLIツールの開発に活用してみてください!

参考

https://www.npmjs.com/package/commander

Discussion