Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8691

CLI のテンプレートプロジェクト by node and TypeScript

$
0
0

node で CLI(Command Line Interface) を開発する機会が数回あって、せっかくなのでテンプレートプロジェクトとしてまとめてみた。

テンプレートプロジェクト

必要なモノ

  • nodejs: v11.13.0+
  • typescript: v3.7.3+

試し方

  1. 上記のリポジトリを Clone する
  2. リポジトリのディレクトリに cd して npm ciする
  3. npm run buildする
  4. npm linkする
  5. source ~/.bash_profileを行うかまたはターミナルを再起動する

これでどのディレクトリでも my-greatコマンドが使用できるようになる。

$my-great hello -f Echizen -s Ooka -a 42

Hello Echizen Ooka.
You're 42 years old.
$my-great something wrong param

Command Line Interface for My great service

  Sample for CLI.

Commands

  my-great hello -f <first_name>-s<second_name>   Say Hello.
  my-great version                                  Show version.

アンインストール

npm uninstall -g @amay/my-great-cli

要点

コマンドライン引数の解析と使用方法の表示

yargsとかいろいろあったけど、自分的に使いやすかったのでこれを選択。

プログラム構成

my-great hello -f <first_name> -s <second_name>   Say Hello.
my-great version                                  Show version.

のように、第一引数を「コマンド」とし、第2引数以降をそのコマンド専用の引数群としたかったので、index.tsで第一引数のみを parse して取得し、コマンド毎に command-xxxx.tsへ委譲している。

command-line-args では commandLineArgs(this.paramDef, { partial: true })partial:trueを設定すると、引数定義(paramDef) に存在しない引数があっても無視する。

cli コマンド名

cliコマンド名 my-greatpackage.jsonbin:で指定している。

package.json

{"name":"@amay/my-great-cli",<省略>"bin":{"my-great":"build/index.js"},<省略>

ビルドされた ./build/index.jsを指すように設定している。
ちなみに npm run 経由で node を実行する場合は、引数の前に --を付ける(例: node ./build/index.js -- version)。

必須引数のチェック

command-line-args では 引数の必須チェックを自力で行わなければならないようなので、定義体の paramDefrequire: booleanを追加し、パースした実際の引数である XxxxConfigrequire = trueな項目が含まれているかをチェックするようにした。

// Valid require paramsconstrequiresNotSetted=this.paramDef.filter(x=>x.require).filter(x=>cfg[x.name]==null).map(x=>`--${x.name}`);if(requiresNotSetted.length>0){console.log(`Param: ${requiresNotSetted.join('')} is required.`);console.log(`------------------------------------`);this.usage[1].optionList=this.paramDef;constusg=commandLineUsage(this.usage)console.log(usg);return-1;}

kebab-case VS camelCase VS snake_case

コマンドの引数は kebab-case がデファクトスタンダードの模様。
command-line-args では commandLineArgs(this.paramDef, { camelCase: true })とすると、--first-nameに渡された引数を、firstName変数に格納してくれる。

が、前述の必須引数のチェックが(定義体と実体の変数名が異なるため)正しく機能しなくなるので妥協案として snake_case の --first_nameを採用している。

コマンドを追加するには

  1. index.tsCommandTypexxxxを増やす
  2. command-xxx.ts(CommandXxxxクラス) を作る
  3. index.tscommandMapに追加する
  4. mainUsageになんか書く

参考


Viewing all articles
Browse latest Browse all 8691

Trending Articles