1
0

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 1 year has passed since last update.

期待の新星@clack/promptsで作る対話型CLI

Last updated at Posted at 2023-02-15

概要

2023/2/13に@clack/promptsがリリースされました。

筆者は今まで対話型CLIで有名なpromptsを使ってきましたが、@clack/promptsは評判も上々(1.9k Stars)なので実際に触ってみたいと思います。

@clack/promptsとは

  • 対話型CLIを作るためのAPI
  • promptsより機能は少ないが 80% 小さいサイズ
  • UIが少しカッコいい

できること

  • テキスト入力
  • テキストのバリデーション
  • 確認分岐
  • 単一選択
  • 複数選択
  • スピナーの表示
  • イントロ、アウトロの表示
  • キャンセル時のCallback

実際に使ってみる

インストール

npm install @clack/prompts

公式にデモが用意されているので、デモのソースをベースに構成してみました。

import { intro, outro, confirm, select, multiselect, spinner, isCancel, cancel, text } from '@clack/prompts';
import { setTimeout as sleep } from 'node:timers/promises';

async function main() {
  intro('ようこそ!');

  // テキスト
  const name = await text({
    message: 'お名前を教えてください',
    placeholder: 'ひみつ', // デフォルト値
    validate(value) {
      // バリデーション
      if (value.length < 2) return 'お名前が間違っています';
    },
  });

  // textがキャンセルされた
  if (isCancel(name)) {
    cancel('バイバイ');
    return process.exit(0);
  }

  // 確認(Yes / No)
  const shouldContinue = await confirm({
    message: `お名前は【${name}】でよろしいですか?`,
  });

  // confirmがキャンセルされた
  if (isCancel(shouldContinue)) {
    cancel('バイバイ');
    return process.exit(0);
  }

  // 単一選択
  const animals = await select({
    message: '好きな動物は?.',
    options: [
      { value: 'cats', label: '' },
      { value: 'dogs', label: '' },
      { value: 'bees', label: 'ハチ', hint: 'これは虫だよ' },
    ],
  });

  // selectがキャンセルされた
  if (isCancel(animals)) {
    cancel('バイバイ');
    return process.exit(0);
  }

  // 複数選択
  const weathers = await multiselect({
    message: '好きな天気は?(いくつでも)',
    options: [
      { value: 'fine', label: '晴れ' },
      { value: 'cloudy', label: '曇り' },
      { value: 'rain', label: '' },
      { value: 'snow', label: '' },
      initialValue: 'snow', // 初期カーソル位置
    ],
  });

  // selectがキャンセルされた
  if (isCancel(weathers)) {
    cancel('バイバイ');
    return process.exit(0);
  }

  // スピナー
  const s = spinner();
  s.start('考え中です...');

  await sleep(3000);

  s.stop('終わりました!');

  outro('さようなら👋');
}

main().catch(console.error);

次にそれぞれの機能を解説していきます。

イントロ表示

プロンプトのイントロを表示します。

  intro('ようこそ!');

実行イメージ

1__.png

公式デモのように、picocolorsなどを使用して文字を修飾することもできます。

intro(color.inverse('ようこそ!'));

実行イメージ

2.png

テキスト入力

テキスト入力を促すプロンプトを実行します。設問文の他にデフォルトとバリデーションが設定できます。

返り値には入力値が格納されているので、後ほど確認プロンプトで設問文に挿入していきます。

// テキスト
const name = await text({
  message: 'お名前を教えてください',
  placeholder: 'ひみつ', // デフォルト値
  validate(value) {
    // バリデーション
    if (value.length < 2) return 'お名前が間違っています';
  },
});

実行イメージ

1___.png

キャンセル

プロンプトの返り値を引数にしてisCancelで判定することで、キャンセル(CTRL + C)時のハンドリングが可能です。

// textがキャンセルされた
if (isCancel(name)) {
  cancel('バイバイ');
  return process.exit(0);
}

実行イメージ

3.png

確認

YesかNoで回答できる確認プロンプトを実行します。

設問文に上で入力したテキストの値を表示してみました。

// 確認(Yes / No)
const shouldContinue = await confirm({
  message: `お名前は【${name}】でよろしいですか?`,
});

実行イメージ

4.png

単一選択

単一選択ではvalueやlabelの他に、選択肢がアクティブな際に表示される注釈も設定できます。

// 単一選択
const animals = await select({
  message: '好きな動物は?.',
  options: [
    { value: 'cats', label: '' },
    { value: 'dogs', label: '' },
    { value: 'bees', label: 'ハチ', hint: 'これは虫だよ' },
  ],
});

実行イメージ

5.png

複数選択

Spaceキーで選択肢を複数個選択できるプロンプトです。
初期カーソル位置を指定することもできます。

// 複数選択
const weathers = await multiselect({
  message: '好きな天気は?(いくつでも)',
  options: [
    { value: 'fine', label: '晴れ' },
    { value: 'cloudy', label: '曇り' },
    { value: 'rain', label: '' },
    { value: 'snow', label: '' },
  ],
  initialValue: 'snow', // 初期カーソル位置
});

実行イメージ

6.png

スピナー

別途oraなどを用意しなくとも、処理中にくるくる回るアレを簡単に表示することができます。
promptsにはない機能です。

// スピナー
const s = spinner();
s.start('考え中です...');

// ... なにかの処理

s.stop('終わりました!');

実行イメージ

7.gif

アウトロ

イントロ同様に最終的に表示されるメッセージを指定することができます。

outro('さようなら👋');

実行イメージ

8.png

まとめ

老舗のpromptsと比べて入力文字のマスキング、オートコンプリート、日付指定などはまだできませんが、単純な対話型CLIなら十分対応できると思いました。何よりサイズが軽量なのとちょっとばかりオシャレなUIが魅力です。

ぜひ対話型CLIを活用して、自分やチーム内で使うちょっとしたツールを開発してみてはいかがでしょうか。

参考

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?