概要
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('ようこそ!');
実行イメージ
公式デモのように、picocolorsなどを使用して文字を修飾することもできます。
intro(color.inverse('ようこそ!'));
実行イメージ
テキスト入力
テキスト入力を促すプロンプトを実行します。設問文の他にデフォルトとバリデーションが設定できます。
返り値には入力値が格納されているので、後ほど確認プロンプトで設問文に挿入していきます。
// テキスト
const name = await text({
message: 'お名前を教えてください',
placeholder: 'ひみつ', // デフォルト値
validate(value) {
// バリデーション
if (value.length < 2) return 'お名前が間違っています';
},
});
実行イメージ
キャンセル
プロンプトの返り値を引数にしてisCancelで判定することで、キャンセル(CTRL + C
)時のハンドリングが可能です。
// textがキャンセルされた
if (isCancel(name)) {
cancel('バイバイ');
return process.exit(0);
}
実行イメージ
確認
YesかNoで回答できる確認プロンプトを実行します。
設問文に上で入力したテキストの値を表示してみました。
// 確認(Yes / No)
const shouldContinue = await confirm({
message: `お名前は【${name}】でよろしいですか?`,
});
実行イメージ
単一選択
単一選択ではvalueやlabelの他に、選択肢がアクティブな際に表示される注釈も設定できます。
// 単一選択
const animals = await select({
message: '好きな動物は?.',
options: [
{ value: 'cats', label: '猫' },
{ value: 'dogs', label: '犬' },
{ value: 'bees', label: 'ハチ', hint: 'これは虫だよ' },
],
});
実行イメージ
複数選択
Spaceキーで選択肢を複数個選択できるプロンプトです。
初期カーソル位置を指定することもできます。
// 複数選択
const weathers = await multiselect({
message: '好きな天気は?(いくつでも)',
options: [
{ value: 'fine', label: '晴れ' },
{ value: 'cloudy', label: '曇り' },
{ value: 'rain', label: '雨' },
{ value: 'snow', label: '雪' },
],
initialValue: 'snow', // 初期カーソル位置
});
実行イメージ
スピナー
別途oraなどを用意しなくとも、処理中にくるくる回るアレを簡単に表示することができます。
promptsにはない機能です。
// スピナー
const s = spinner();
s.start('考え中です...');
// ... なにかの処理
s.stop('終わりました!');
実行イメージ
アウトロ
イントロ同様に最終的に表示されるメッセージを指定することができます。
outro('さようなら👋');
実行イメージ
まとめ
老舗のpromptsと比べて入力文字のマスキング、オートコンプリート、日付指定などはまだできませんが、単純な対話型CLIなら十分対応できると思いました。何よりサイズが軽量なのとちょっとばかりオシャレなUIが魅力です。
ぜひ対話型CLIを活用して、自分やチーム内で使うちょっとしたツールを開発してみてはいかがでしょうか。
参考