コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

対話型CLIライブラリのInquirer.jsを試してみた

はじめに

この記事は「コドモン Advent Calendar 2023」9日目の記事です!

qiita.com

こんにちは、コドモンプロダクト開発部の尾沼です。 最近対話型CLIアプリを作成してみたいなと思い、Node.jsやシェルスクリプトで入門してみました。 対話型CLIのイメージとしては、Vue CLIが挙げられます。

Vue CLI

複雑なプロンプトでも容易に実装できる方法がないか調べていたところ、対話型CLIアプリを簡単に実装できるInquirer.jsというライブラリを見つけたのでご紹介します。

Inquirer.jsとは

Inquirer.jsは、Node.jsを使用した対話型CLIアプリの作成を手助けするライブラリです。 これを使えば、さまざまな形式の質問をユーザーへ簡単に投げかけることができます。 GitHubでは18.8kのスターを獲得しており、執筆時点での開発も行われています。 TypeScriptにも対応していますが、今回はJavaScriptでの使用例を見ていきたいと思います。

インストール方法

$ npm install @inquirer/prompts
# or
$ yarn add @inquirer/prompts

使い方

もしjsファイルを実行した際にnode:61554) Warning: To load an ES module, set “type”: “module” in the package.json or use the .mjs extension.というエラーが出た方は、package.jsonに以下を入力してください。

"type": "module"

ユーザーからテキスト入力を受け取る

import { input } from "@inquirer/prompts";

async function askForProjectName() {
  const answer = await input({ message: "プロジェクト名を入力してください:" });
  console.log(answer);
}

askForProjectName();

ユーザーから複数の選択を受け取る

いわゆるチェックボックスです。

import { checkbox } from '@inquirer/prompts';

async function selectProgrammingLanguages() {
  const answer = await checkbox({
    message: "あなたが使用するプログラミング言語を選んでください(複数選択可)",
    choices: [
      { name: "JavaScript", value: "JavaScript" },
      { name: "Python", value: "Python" },
      { name: "Java", value: "Java" },
    ],
  });

  console.log(answer);
}

selectProgrammingLanguages();

ユーザーから単一の選択を入力させる

ラジオボタンのようなものも簡単に実装できます。

import { select } from '@inquirer/prompts';

async function choosePackageManager() {
  const answer = await select({
    message: "使用するパッケージマネージャーを選んでください",
    choices: [
      {
        name: "npm",
        value: "npm",
      },
      {
        name: "yarn",
        value: "yarn",
      },
    ],
  });

  console.log(answer);
}

choosePackageManager();

ユーザーにYesかNoかを選択させる

defaultオプションをfalseに設定すると、Noがデフォルトの選択肢になります。 confirmメソッドの戻り値はboolean型です。 これにより、ユーザーが簡潔にYes/Noで答えることができるようになります。

import { confirm } from '@inquirer/prompts';

async function askToContinue() {
  const answer = await confirm({
    message: "続けますか?",
    default: false, // デフォルトをNoに設定
  });
  console.log(answer);
}

askToContinue();

他にもパスワード入力に対応したプロンプトなども用意されています。

実際に試してみた

ユーザーが「Y」と回答した場合にghコマンドで特定のActionsのワークフローを実行するような簡易プログラムを書いてみました。

import { confirm } from '@inquirer/prompts';
import { exec } from "child_process";

async function runWorkflow() {
  const shouldRun = await confirm({ message: "ワークフローを実行しますか?" });
  if (!shouldRun) {
    console.log("実行しませんでした。");
    return;
  }

  exec(
    "gh workflow run actions.yml --raw-field message='テスト'",
    (error, stdout, stderr) => {
      if (error) {
        console.error(error);
        return;
      }
      if (stderr) {
        console.error(stderr);
        return;
      }
    }
  );
}

runWorkflow();

このコードのように、Inquirer.jsを使用すればユーザーの回答を簡単に取り入れることができます。

試してみた感想

まだ本格的に使用していないものの、個人的に以下の点が魅力的だと感じました。

  • ビジュアル的にリッチでユーザーフレンドリーな対話型CLIを開発できる
  • チェックボックスやラジオボタンのようなものを簡単かつシンプルに実装できる
  • 入力判定処理がライブラリ側で実装されてるメソッドもあるため、コードの量を減らすことができる

終わりに

類似のライブラリとしては、enquirerpromptsもあります。 今回初めて対話型CLIアプリを作成するにあたり、現在も開発が進んでいて情報が豊富で、入門しやすいInquirer.jsを選びました。 ライブラリを使わずとも、ユーザーからの文字列を受け取る程度なら簡単に実装できますが、チェックボックスやラジオボタンで回答してもらう複雑な質問を実装するのは大変です。 しかしInquirer.jsのような対話型CLIアプリの作成を支援するライブラリを用いれば、Vue CLIのようなアプリも容易に開発することができます。

もし少しでも興味が湧いたら、ぜひ試してみてください!