naopoyo.com
  • Docs
  • Tags
  • Bookmarks
  • Tools
  • About
  • Docs
  • Tags
  • Bookmarks
  • Tools
  • About

目次

© naopoyo

目次

最近更新された記事

🧜‍♀️

beautiful-mermaid を使ってみた

1日前·2026年02月01日
  • Markdown
📦

Changesets でモノレポのリリースを自動化する(個人開発向け設定)

1日前·2026年01月31日
  • Changesets
  • npm
  • GitHub
🎤

GitHub Actions で npm パッケージを公開する(アルファ版向け簡易フロー)

1日前·2026年01月31日
  • GitHub
  • npm
🐝

CLI ツール開発初心者のためのまとめ

公開日約6時間前2026-02-01
履歴GitHubで見る
MarkdownRaw Content
  • Node.js
  • npm
  • bash

はじめに

Node.js で CLI ツールを作成する際に知っておきたい知識をまとめました。設定ファイルの配置場所、コマンド設計、テストしやすい設計など、実践的な内容を解説します。

設定ファイルの配置場所

CLI ツールを作ると、ほぼ必ず「設定ファイルをどこに置くか」という問題に直面します。

よくある配置パターン

パターン例用途
ホームディレクトリ直下~/.mytoolrc, ~/.mytool/レガシー。古いツールに多い
XDG 準拠~/.config/mytool/モダン。新しいツールの主流
プロジェクトローカル./.mytool/, ./mytool.config.jsプロジェクト固有の設定

有名ツールの設定ファイル配置

ツール配置場所備考
Git~/.gitconfig歴史的標準。現在は ~/.config/git/config も公式サポート。
SSH~/.ssh/config変更不可。ディレクトリ権限(700)に非常に厳しい。
AWS CLI~/.aws/AWS_SHARED_CREDENTIALS_FILE 等の環境変数で変更は可能。
npm~/.npmrcレガシー。NPM_CONFIG_USERCONFIG で移動自体は可能。
Neovim~/.config/nvim/init.luaXDG準拠。macOSでも ~/.config を使うのが一般的。
VS Code~/.config/Code/ (Linux)macOS: ~/Library/Application Support/Code/
Windows: %APPDATA%\Code\
Docker~/.docker/config.jsonDOCKER_CONFIG 環境変数で場所を変更可能。
Zsh~/.zshrc基本はホーム直下。ZDOTDIR を設定すれば移動可能。

古いツールはホームディレクトリ直下、新しいツールは ~/.config/ 以下に配置する傾向があります。

XDG Base Directory Specification

XDG とは?

XDG Base Directory Specification は、freedesktop.org が策定した Linux/Unix 系 OS での設定ファイルやデータの保存場所の標準仕様です。

「ホームディレクトリがドットファイルだらけになる問題」を解決するために生まれました。

主なディレクトリ

環境変数デフォルト用途例
XDG_CONFIG_HOME~/.config設定ファイル~/.config/git/config
XDG_DATA_HOME~/.local/shareアプリデータ~/.local/share/nvim/
XDG_CACHE_HOME~/.cacheキャッシュ~/.cache/npm/
XDG_STATE_HOME~/.local/stateログ、履歴~/.local/state/bash/history

実装のポイント

XDG 準拠の設定パスを取得する際は、以下の順序で決定します:

  1. 環境変数 XDG_CONFIG_HOME が設定されていればそれを使用
  2. 未設定なら ~/.config をデフォルトとして使用

なぜ環境変数をチェックするのか?

ユーザーが XDG_CONFIG_HOME=/custom/path と設定している場合、それを尊重するのがマナーです。CI 環境やコンテナ環境で設定場所を変えたいケースは意外と多いです。

Windows での扱い

XDG は Linux/Unix 向けの仕様ですが、Windows でも ~/.config/ を使うツールが増えています。

選択肢は2つあります:

  1. Windows ネイティブを尊重 - %APPDATA% (C:\Users\username\AppData\Roaming) を使用
  2. XDG で統一 - Windows でも ~/.config/ を使用

開発者向け CLI なら Windows でも ~/.config/ で統一するのもアリです。WSL を使う開発者にとっては、パスが統一されている方が便利だからです。

XDG 準拠のメリット

  1. ホームディレクトリがすっきり - ls -la ~ がドットファイルだらけにならない
  2. バックアップが容易 - ~/.config をバックアップすれば全設定が保存される
  3. 一貫性 - どのツールも同じ場所に設定がある
  4. カスタマイズ可能 - 環境変数で配置場所を変更できる

コマンド設計パターン

サブコマンドパターン

大きな CLI ツールは、サブコマンドで機能を分割します。

# Git スタイル
git config --list
git config get user.name
git config set user.name "John"

# npm スタイル
npm config list
npm config get registry
npm config set registry https://...

# AWS CLI スタイル
aws configure list
aws configure get region
aws configure set region ap-northeast-1

共通オプションの設計

# スコープを指定するオプション
git config --global user.name    # ユーザー設定
git config --local user.name     # プロジェクト設定
git config --system user.name    # システム設定

設計のポイント:

  • -g, --global のように短縮形も用意する
  • デフォルトの挙動を明確にする(読み取りはマージ、書き込みはローカル、など)

出力形式のオプション

# 人間向け(デフォルト)
mytool config list

# スクリプト向け
mytool config list --json
mytool config get key --raw

スクリプトから使われることを想定して、機械可読な出力形式を用意しておくと喜ばれます。

テストしやすい設計

CLI ツールでもテストは重要です。

依存性注入(Dependency Injection)

外部依存(ファイルシステム、ネットワーク、ユーザー入力など)を注入可能にすることで、テスト時にモックに差し替えられます。

テストしにくい設計の特徴:

  • グローバルな fs モジュールを直接使用
  • process.cwd() や os.homedir() を関数内で直接呼び出し
  • console.log を直接使用

テストしやすい設計の特徴:

  • 外部依存を引数として受け取る(デフォルト値は本物を使用)
  • パスを返す関数を注入可能にする
  • ロガーを注入可能にする

注入すべき主な依存

依存理由
ファイルシステム (fs)ファイルの存在や内容をモックしたい
プロンプト (inquirer)ユーザー入力をモックしたい
ロガー (console)出力をキャプチャしたい
現在時刻 (Date.now)日付に依存するテストを安定させたい
環境変数異なる環境をシミュレートしたい

ユーザーフレンドリーな出力

色付き出力

ターミナル出力に色をつけると、情報が読みやすくなります。

色用途
緑成功、完了
赤エラー
黄警告
シアン情報、キー名
薄い色(dim)補足情報、パス
太字強調

主なライブラリ:

ライブラリサイズ特徴
picocolors2.6 KB最軽量、依存なし
kleur8 KBシンプル
chalk44 KB機能豊富

軽量さを求めるなら picocolors がおすすめです。

スピナー(進捗表示)

時間のかかる処理には進捗表示を出すと、ユーザーが「固まった?」と不安にならずに済みます。

ora ライブラリが定番です。

テーブル出力

設定一覧などを表示する際は、テーブル形式が見やすいです。cli-table3 などのライブラリが使えます。

エラーハンドリング

終了コード

CLI ツールは適切な終了コードを返すべきです。

コード意味
0成功
1一般的なエラー
2引数エラー

ユーザーフレンドリーなエラーメッセージ

悪い例:

Error: ENOENT: no such file or directory

良い例:

Error: Configuration file not found
Expected: ~/.config/mytool/config.json

Run "mytool init" to create a configuration file.

ポイント:

  • 何が問題かを明確に
  • どこで問題が起きたかを示す
  • 解決方法を提案する

Ctrl+C のハンドリング

インタラクティブプロンプト中に Ctrl+C が押された場合、エラーではなく「キャンセルされた」として扱い、正常終了(exit code 0)するのが一般的です。

参考リンク

  • XDG Base Directory Specification
  • Commander.js
  • Inquirer.js
  • picocolors
  • ora