7
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.

GoodpatchAdvent Calendar 2023

Day 12

CLIのUI開発支援するためのNPMライブラリ: rich-cli をTSで実装&公開しました

Last updated at Posted at 2023-12-11

こんなものを作って公開しました

CharRenderer

char.gif

import { ANSIEscSeqHelper, CharRenderer, CharStyle, Color } from "rich-cli"

const charRederer = new CharRenderer()

charRederer.writeLine('aaa')
charRederer.addIndent()
charRederer.writeLine('bbb')
charRederer.addIndent()
ANSIEscSeqHelper.changeCharStyle(new CharStyle('underline'))
ANSIEscSeqHelper.changeColor(new Color('green'))
charRederer.writeLine('ccc')
charRederer.reduceIndent()
ANSIEscSeqHelper.changeColor(new Color('red'))
ANSIEscSeqHelper.changeCharStyle(new CharStyle('bold'))
charRederer.writeLine('ddd')
charRederer.reduceIndent()
ANSIEscSeqHelper.resetCharAllStyle()
charRederer.writeLine('eee')

Progress

progress.gif

import { Progress } from "rich-cli"

const progress = new Progress(2562)
let n = 0

while (!progress.isComplete()) {
  n++
  progress.incrementProgress()
  if (n % 100 === 0) progress.message(`${n} completed!⭐`)
  progress.render()
  await sleep(2)
}

Spin

spin.gif

import { ANSIEscSeqHelper, Color } from "rich-cli"

const stopSpin = ANSIEscSeqHelper.spin(new Color('magenta'))
await sleep(3000)
stopSpin()

Confirm

t-rec_5.gif

import { PromptHelper } from "rich-cli"

const yn = await PromptHelper.askConfirm('Are you sure?')
if (yn) {
  console.log('Yes')
} else {
  console.log('No')
}

実装の仕組み

ANSI Escape Sequences(Code?)を使って、リッチな描画を試みました。

参考資料

ライブラリを公開するためのバンドラなどはこちらの記事を参考にさせてもらいました。
https://zenn.dev/dqn/articles/npm-publishing-2023
昨今の開発事情で、webpack等のツールは不慣れになってしまいました。
tsupというバンドラを使用しています。
zero-configでとても使いやすかったです。

今後の展望

正直にまだまだ低品質なので磨きたい。

  • 抽象化
    • 低次元なAPIを使って制御する部分があるので、より高次元なAPIのみで実装ができるようなものにしたい
  • より使いやすいインターフェイス
    • 他の類似ライブラリを参考にしてみよう
  • 機能拡張
    • セレクトUI
    • トグルUI
    • クリッカブルウェブリンク
  • 耐久性
    • ものすごく小さい画面(1行30文字未満)だとプログレスバーがバグる
    • 他にも、並行に文字を出力したりすると、きっとバグる
  • テスト
    • 急いで作ったので省略した
    • どうやって実装するかはまだ分かってない
      • コンソールの状態をどうやってテストしよう?
      • 標準出力をリダイレクトして、テキストを検査する?
      • 他の類似ライブラリを参考にしてみよう
  • ノウハウ公開
    • カーソル操作・コンソールの描画周り非常にわかりづらいので、しっかり勉強して情報をまとめて記事書きたい

困難だった点

  • そもそも、この手の技術についてのドキュメントが少ない...
  • カーソルの操作について、いまだによくわからない部分がある
    • 画面端の挙動
    • scroll, save,\n,cursor down/up など、コンソールの仕様がよく分かっていないことが明らかになった...
      • この辺、体系的に勉強するにはどうしたらいいんだろう。
        • たぶん、各コンソールの勉強をすることになるのかな?
    • カーソルがある位置までしか、コンソールに描画されないんだ...とか。
  • ANSIエスケープシーケンス
    • 情報がまとまって落ちてない

おまけ(感想)

CLIを開発する時って、なんだか無味乾燥なものしか出来上がらないので
自分用に開発をリッチにするものがあれば良いなぁ...と思い、作り始めました。

意外と詰まるポイントがあって、悶々としました。
未理解な点については整理して、またどこかで記事にしようかなと思ったり。

あとは、それぞれの機能でライブラリを分けようかなと思ったりもするが
オールインワンなライブラリの方がお手軽にインストールできるので、使いやすそうと思ったり。

後になって車輪の再開発だったかもなぁと思ったりしました。

他の魅力的なCLI開発支援系ライブラリたち
https://github.com/nathanpeck/clui
https://github.com/patorjk/figlet.js
https://github.com/yeoman/update-notifier
https://github.com/sindresorhus/terminal-link
https://github.com/sindresorhus/log-symbols

ただ、ライブラリの開発は少し憧れていたことだったので、達成できたのでヨシ。
今後も自分のためにライブラリ開発はしていくかも。

import { Progress } from "rich-cli" // P.S: これが動くと感動する。
7
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
7
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?