このドキュメントでは、milistennaの技術構成とプロジェクト構造について説明します。
-
React v19: UIライブラリ
- React Compiler対応により、最適化されたレンダリング(ビルド時)
- StrictModeでの開発
-
TypeScript (tsgo v7 native-preview): 型安全な開発
- ネイティブ版TypeScriptコンパイラによる高速な型チェック
- 厳密な型チェック(
strict: true)
-
Vite v7: ビルドツール
- 高速な開発サーバー(ポート5123)
- 最適化されたプロダクションビルド
- TanStack Router v1
- 型安全なルーティング
- ファイルベースルーティング(Viteプラグインによる自動生成)
- 遅延ローディング対応(
.lazy.tsxファイル) - ルートコンテキストでの認証状態共有
- TanStack Query v5
- サーバー状態の管理
- キャッシング(デフォルト5分のstaleTime)
- バックグラウンド更新
- Yamada UI v2
- React用のUIコンポーネントライブラリ
- カラーモード対応(ライト/ダーク)
- レスポンシブデザイン
- アクセシビリティ対応
- Zustand v5
- 軽量な状態管理ライブラリ
- ローカルストレージへの永続化(
persistミドルウェア) - ログイン状態の管理
- TanStack Form v1
- 型安全なフォーム処理
- Zodによるバリデーション統合
- Zod v4
- スキーマベースのバリデーション
- TypeScriptとの統合
- misskey-js v2026
- Misskey APIのTypeScript定義
- エンティティ型の提供
- APIエンドポイント型の提供
- @phosphor-icons/react: アイコンライブラリ
- uuid: MiAuth用のセッションID生成
- use-debounce: ユーザー検索のデバウンス処理
- Biome v2: リンターとフォーマッター
- @vitejs/plugin-react-swc: 開発時のSWCによる高速コンパイル
- @vitejs/plugin-react: ビルド時のReact Compiler対応
- mise: Node.jsとpnpmのバージョン管理
milistenna/
├── public/ # 静的ファイル
│ ├── 192.png # PWAアイコン (192x192)
│ ├── 512.png # PWAアイコン (512x512)
│ ├── apple-touch-icon.png
│ ├── favicon.ico
│ └── site.webmanifest # PWAマニフェスト
├── src/
│ ├── @types/ # TypeScript型定義
│ │ └── vite-env.d.ts
│ ├── apis/ # API呼び出しロジック
│ │ ├── useApiQuery.ts # API呼び出しの基本フック
│ │ ├── antennas/ # アンテナ関連API
│ │ │ ├── useGetAntennasList.ts
│ │ │ └── useGetAntennasShow.ts
│ │ ├── lists/ # リスト関連API
│ │ │ ├── useGetUsersListsList.ts
│ │ │ └── useGetUsersListsShow.ts
│ │ └── users/ # ユーザー関連API
│ │ ├── useGetUsersFollowing.ts
│ │ ├── useGetUsersSearchByUsernameAndHost.ts
│ │ └── useGetUsersShow.ts
│ ├── components/ # Reactコンポーネント
│ │ ├── Header.tsx # ヘッダーコンポーネント
│ │ ├── HeaderMenu.tsx # ヘッダーメニュー(カラーモード切替、ログアウト)
│ │ ├── common/ # 汎用コンポーネント
│ │ │ ├── Confirm.tsx
│ │ │ ├── EmptyState.tsx
│ │ │ ├── ExternalLinkButton.tsx
│ │ │ ├── FloatLinkButton.tsx
│ │ │ ├── LimitAlert.tsx
│ │ │ ├── LinkButton.tsx
│ │ │ ├── Loader.tsx
│ │ │ └── layout/ # レイアウト関連
│ │ │ ├── GridCard.tsx
│ │ │ └── GridContainer.tsx
│ │ └── domain/ # ドメイン固有コンポーネント
│ │ └── user/
│ │ ├── AddUserModal.tsx
│ │ └── UserCard.tsx
│ ├── routes/ # ルート定義(TanStack Router)
│ │ ├── __root.tsx # ルートレイアウト
│ │ ├── index.tsx # トップページ(ローダー)
│ │ ├── index.lazy.tsx # トップページ(コンポーネント)
│ │ ├── _auth/ # 認証が必要なルート
│ │ │ ├── route.tsx # 認証ガード
│ │ │ ├── antenna/ # アンテナ管理
│ │ │ │ ├── index.lazy.tsx # アンテナ一覧
│ │ │ │ ├── $edit.tsx # 編集/作成ローダー
│ │ │ │ ├── $edit.lazy.tsx # 編集/作成フォーム
│ │ │ │ └── -components/ # ルート専用コンポーネント
│ │ │ └── list/ # リスト管理
│ │ │ ├── index.lazy.tsx # リスト一覧
│ │ │ ├── $edit.tsx # 編集ローダー
│ │ │ ├── $edit.lazy.tsx # 編集フォーム
│ │ │ └── -components/ # ルート専用コンポーネント
│ │ └── login/ # ログイン関連
│ │ ├── route.tsx # ログイン済みリダイレクト
│ │ ├── index.tsx # ログインページ
│ │ └── getToken/ # トークン取得
│ ├── store/ # 状態管理
│ │ └── login.ts # ログイン状態
│ ├── theme/ # テーマ設定
│ │ └── index.ts # Yamada UIテーマ・コンフィグ
│ ├── utils/ # ユーティリティ関数
│ │ ├── fetcher.ts # API呼び出しの基本関数
│ │ ├── getApiUrl.ts # APIのURL生成
│ │ ├── getFetchObject.ts # fetchリクエストオブジェクト生成
│ │ ├── isError.ts # Misskey APIエラー判定
│ │ ├── keywords.ts # キーワード配列⇔文字列変換
│ │ └── queryConfig.ts # TanStack Queryのデフォルト設定
│ ├── App.tsx # アプリケーションルート
│ ├── main.tsx # エントリーポイント
│ └── routeTree.gen.ts # 自動生成されたルート定義
├── docs/ # ドキュメント
├── biome.json # Biome設定
├── mise.toml # mise設定(Node.js/pnpmバージョン)
├── package.json # プロジェクト設定
├── tsconfig.json # TypeScript設定(プロジェクトリファレンス)
├── tsconfig.base.json # TypeScript基本設定
├── tsconfig.app.json # アプリケーションTS設定
├── tsconfig.node.json # Node.js用TS設定
├── vite.config.ts # Vite設定
└── tsr.config.json # TanStack Router設定
Misskey APIとの通信を担当するカスタムフック群。各エンドポイントに対応したフックとqueryOptionsが定義されています。
useApiQuery.ts: API呼び出しの基本ロジック(エラーハンドリング含む)antennas/: アンテナ関連のAPI呼び出しlists/: リスト関連のAPI呼び出しusers/: ユーザー関連のAPI呼び出し(検索、フォロー、詳細取得)
Reactコンポーネントを分類して配置。
- Header.tsx / HeaderMenu.tsx: アプリケーション全体のヘッダー
- common/: 汎用的なコンポーネント(ボタン、ローダー、確認ダイアログ、上限アラートなど)
- common/layout/: レイアウトコンポーネント(グリッドカード、グリッドコンテナ)
- domain/: ドメイン固有のコンポーネント(ユーザーカード、ユーザー追加モーダルなど)
TanStack Routerのファイルベースルーティングに従った構造。-プレフィックスのディレクトリ(-components/)はルート生成から除外され、ルート専用コンポーネントの配置に使用されます。
- _auth/: 認証が必要なルート(プレフィックス
_はレイアウトルート) - _auth/antenna/: アンテナ管理ページ群
- _auth/list/: リスト管理ページ群
- login/: ログイン関連のルート
- __root.tsx: すべてのルートの親となるレイアウト
Zustandを使用したグローバル状態管理。
- login.ts: ログイン状態(
isLogin,token,instance,mySelf)
共通のユーティリティ関数。
- fetcher.ts: misskey-jsのエンドポイント型を使った型安全なAPI呼び出し関数(カリー化)
- getApiUrl.ts: APIのURL生成(
https://{instance}/api/{endpoint}形式) - getFetchObject.ts: POSTリクエストのbodyとheadersを生成(トークン自動付与)
- isError.ts: Misskey APIのエラーレスポンス判定
- keywords.ts: キーワード2次元配列と表示用文字列の相互変換
- queryConfig.ts: TanStack Queryのデフォルト設定(5分のstaleTime、2回のリトライ)
User Action
↓
Component
↓
Custom Hook (useApiQuery + queryOptions)
↓
fetcher (カリー化された関数)
↓
getFetchObject (トークン付与)
↓
getApiUrl (URL生成)
↓
fetch API → Misskey API
↓
TanStack Query (Cache)
↓
Component (Re-render)
- ユーザーがインスタンス名を入力(Zodでドメイン形式をバリデーション)
/api/endpointsを呼び出してmiauth/gen-tokenの対応を確認- UUIDでセッションIDを生成し、MiAuth URLにリダイレクト
- ユーザーが認証を許可後、コールバックURLに戻る
/api/miauth/{sessionId}/checkでトークンを取得/api/iでユーザー情報を取得- Zustandストアに保存 → ローカルストレージに永続化
TanStack Routerを使用した型安全なルーティング。
| パス | 説明 |
|---|---|
/ |
トップページ(リスト管理・アンテナ管理への導線) |
/login |
ログインページ |
/login/getToken |
トークン取得(MiAuthコールバック) |
/list |
リスト一覧(認証必須) |
/list/:edit |
リスト編集(認証必須) |
/antenna |
アンテナ一覧(認証必須) |
/antenna/:edit |
アンテナ編集/作成(認証必須、createで新規作成) |
- ファイルベースルーティング(
@tanstack/router-plugin/viteで自動生成) - 遅延ローディング(
.lazy.tsxファイル) - ルートコンテキストで認証状態とQueryClientを共有
_authレイアウトで認証ガード(未認証時は/loginにリダイレクト)loginレイアウトで認証済みガード(認証済みの場合は/にリダイレクト)
Yamada UIのコンポーネントとテーマシステムを使用。
- カラーモード(ライト/ダーク)対応
- レスポンシブデザイン
- カスタムテーマ設定(
src/theme/) - グラスモーフィズム効果のヘッダー
- tsgo(TypeScript native preview)による型チェック
- React Compilerによる最適化(ビルド時のみ、
babel-plugin-react-compiler) - Viteによるバンドル
- 静的ファイルの生成
- React Compilerによる自動最適化(ビルド時)
- 開発時はSWCプラグインによる高速コンパイル
- TanStack Routerの遅延ローディング
- TanStack Queryのキャッシング
- ルートローダーによるデータのプリフェッチ