はじめに
2025年を振り返ると、私にとって生成AIはシステム開発において欠かせない存在になりました。特にコードリーディングでは、Gemini CLI を活用することでリポジトリ全体の理解を高速化できます。
その効率をさらに高めるために、リポジトリを生成AIが読みやすいテキストに変換する Gitingest を導入しています。本記事では、GitingestとGemini CLIを組み合わせてコードリーディングを加速する方法を、私の2025年の実践知として紹介します。
生成AIとコードリーディングの現在地
従来は、リポジトリを理解するのに時間がかかるのが課題でした。
Gemini CLIを使うと、コードやドキュメントを解析して自然言語で説明を生成でき、理解のスピードが格段に向上します。新しいプロジェクトや未使用のオープンソースライブラリを選定する際に、Gemini CLIと対話しながら理解を深めることが増えてきました。
ただし、2025年時点の生成AIでは、開発リポジトリ全体を丸ごと読み込ませても十分な結果が得られないことがあります。コンテキスト量が増えすぎると、AIが全体を保持しきれないためです。そのため、構造化して情報量を絞り、段階的に理解させるのが効率的です。
では、具体的にはどのように範囲を絞っていくべきでしょうか?
生成AIに指示を出す人も新たにプロジェクトに参画した時や使ったことのないオープンソースライブラリを選定するときには「何がわからないかわからない」という状態だと思います。
例えば、Gemini CLI に bulletproof-react のリポジトリをクローンした状態で質問してみると、まず README.md を読みにいき概要を把握した上で回答してくれます。しかし、README.md だけでは得られる情報に限界があります。手当たり次第にリポジトリを掘っていく方法もありますが、効率的とは言えません。
そこで登場するのが Gitingest です。
Gitingest を使うと、リポジトリ全体を生成AIが読みやすいテキストに変換でき、Gemini CLI に効率的に理解させることができます。次の章では、Gitingest の使い方と活用法を詳しく紹介します。
以下は README.md を読んだだけの状態の Gemini CLI の回答結果です。少し物足りないかなと感じます。
███ █████████ ██████████ ██████ ██████ █████ ██████ █████ █████
░░░███ ███░░░░░███░░███░░░░░█░░██████ ██████ ░░███ ░░██████ ░░███ ░░███
░░░███ ███ ░░░ ░███ █ ░ ░███░█████░███ ░███ ░███░███ ░███ ░███
░░░███ ░███ ░██████ ░███░░███ ░███ ░███ ░███░░███░███ ░███
███░ ░███ █████ ░███░░█ ░███ ░░░ ░███ ░███ ░███ ░░██████ ░███
███░ ░░███ ░░███ ░███ ░ █ ░███ ░███ ░███ ░███ ░░█████ ░███
███░ ░░█████████ ██████████ █████ █████ █████ █████ ░░█████ █████
░░░ ░░░░░░░░░ ░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░
Tips for getting started:
1. Ask questions, edit files, or run commands.
2. Be specific for the best results.
3. /help for more information.
> このリポジトリを読み込み、日本語で説明してください。
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile README.md │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ このリポジトリ「Bulletproof
React」は、堅牢で拡張性が高く、かつ保守しやすいReactアプリケーションを構築するためのアーキテクチャ設計ガイド、およびその実装例です。
Reactのエコシステムは自由度が高い反面、標準的な構成が存在しないため、大規模になるとコードベースが複雑化しやすいという問題があります。このプロジェクトは、そ
うした問題に対する一つの解として、ベストプラクティスと具体的なディレクトリ構成、技術選定の指針を提供しています。
主な特徴と目的
* スケーラビリティ: チームやコードベースの規模が大きくなっても破綻しにくい構成。
* 関心の分離: 機能ごとに明確に境界を分けたディレクトリ構造(Featuresパターンなど)。
* 実践的なベストプラクティス: テスト、セキュリティ、パフォーマンス、状態管理など、実開発で直面する課題への対処法を網羅。
リポジトリの構成
リポジトリ内にはドキュメントのほか、以下の3つの主要なサンプルアプリケーション(apps/ 配下)が含まれており、それぞれの環境に応じた実装例を確認できます。
1. `react-vite`: Viteを使用した標準的なSPA(シングルページアプリケーション)構成。
2. `nextjs-app`: Next.jsのApp Routerを使用した構成。
3. `nextjs-pages`: Next.jsの従来のPages Routerを使用した構成。
また、docs/ フォルダには、API層の設計、コンポーネント設計、ディレクトリ構造の解説など、詳細な解説ドキュメントが含まれています。
一言で言えば、「Reactプロジェクトを迷わずに始めるための、実践的な設計図」です。
Using: 1 GEMINI.md file | 2 MCP servers
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ > Type your message or @path/to/file │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
~/.../bulletproof-react (master*)
Gitingestでリポジトリ情報をAI向けに変換
Gitingest は、Git リポジトリの URL やローカルディレクトリをもとに、生成AI向けに最適化されたテキストを出力するツールです。これを用いて、リポジトリ全体の情報を整理し、情報量を適切に絞って AI に理解させることができます。
例えば、ブラウザ版では公開リポジトリを対象にテキストを生成できます。プライベートリポジトリの場合は、コマンドラインから出力することも可能です。
# Basic usage (writes to digest.txt by default)
gitingest /path/to/directory
このように生成されたテキストファイル( @gitingest/alan2207-bulletproof-react.txt )を Gemini CLI に読み込ませると、README.md のみを読んだ状態よりも格段に解像度の高い説明を得ることができます。
AI がリポジトリ構造や関連ファイルを把握した状態で質問できるため、自身の理解を深める「壁打ち」として非常に有効です。
███ █████████ ██████████ ██████ ██████ █████ ██████ █████ █████
░░░███ ███░░░░░███░░███░░░░░█░░██████ ██████ ░░███ ░░██████ ░░███ ░░███
░░░███ ███ ░░░ ░███ █ ░ ░███░█████░███ ░███ ░███░███ ░███ ░███
░░░███ ░███ ░██████ ░███░░███ ░███ ░███ ░███░░███░███ ░███
███░ ░███ █████ ░███░░█ ░███ ░░░ ░███ ░███ ░███ ░░██████ ░███
███░ ░░███ ░░███ ░███ ░ █ ░███ ░███ ░███ ░███ ░░█████ ░███
███░ ░░█████████ ██████████ █████ █████ █████ █████ ░░█████ █████
░░░ ░░░░░░░░░ ░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░
Tips for getting started:
1. Ask questions, edit files, or run commands.
2. Be specific for the best results.
3. /help for more information.
> @gitingest/alan2207-bulletproof-react.txt を読み込み、日本語で説明してください
✦ はい、承知いたしました。このリポジトリ(Bulletproof React)は、Reactアプリケーション開発における多くの重要な側面をカバーしています。
以下の主要な観点(ドキュメントの章立てに基づく)から、特に詳しく知りたいものを選んでいただけますか?
1. 🗄️ プロジェクト構造 (Project Structure)
* 機能(Feature)ベースのフォルダ構成
* 単方向のコードフロー制限(循環参照の防止)
* 絶対パスインポートの活用
2. 📡 API レイヤー (API Layer)
* APIクライアントのシングルトン化(Axios/Fetchラッパー)
* APIリクエスト定義とフックの分離
* データ取得ライブラリ(React Query等)の活用
3. 🧱 コンポーネントとスタイリング (Components & Styling)
* コンポーネント設計(Propsの制限、コロケーション)
* UIライブラリの抽象化(Headless UI + Tailwindなど)
* Storybookの活用
4. 🗃️ 状態管理 (State Management)
* 状態の分類(サーバーキャッシュ、UI状態、フォーム状態、URL状態)
* Context API vs 外部ライブラリ(Zustand, Jotaiなど)の使い分け
5. ⚠️ エラー処理 (Error Handling)
* APIエラーのインターセプトと通知
* Error Boundaryによるコンポーネントレベルのエラー捕捉
6. 🔐 セキュリティ (Security)
* 認証(JWT, Cookie vs LocalStorage)
* 認可(RBAC: ロールベース / PBAC: パーミッションベース)
* XSS対策
7. 🧪 テスト (Testing)
* テストピラミッド(ユニット < 統合 < E2E)
* MSW (Mock Service Worker) によるAPIモック
* Testing Library と Playwright の活用
8. 🚄 パフォーマンス (Performance)
* コード分割(Code Splitting)
* 再レンダリングの最適化
* Core Web Vitals対策
9. ⚙️ プロジェクト標準 (Project Standards)
* ESLint, Prettier, TypeScriptの設定
* HuskyによるGitフック
* 命名規則の強制
どれから深掘りしましょうか?(複数選択や、具体的な悩み相談でも構いません)
bulletproof-react を生成AIに解説してもらう
それでは、この状態で生成AIにリポジトリの解説をしてもらいます。React 開発のベストプラクティスをまとめた bulletproof-react を題材にします。
> 1. プロジェクト構造を解説してほしい
✦ 承知いたしました。「🗄️ プロジェクト構造 (Project Structure)」について解説します。
このリポジトリ(Bulletproof
React)が提案する構造は、「機能(Feature)ベース」のアーキテクチャを採用している点が最大の特徴です。アプリが大規模になっても、コードがスパゲッティ化しにく
いように設計されています。
1. src ディレクトリの基本構成
まず、ルートとなる src フォルダは以下のような役割分担になっています。
1 src
2 ├── app # アプリの「組み立て」層(ルーティング、プロバイダー設定など)
3 ├── assets # 画像やフォントなどの静的ファイル
4 ├── components # アプリ全体で使う「共有」コンポーネント(Button, Inputなど)
5 ├── config # 環境変数やグローバルな設定
6 ├── features # ★ここが核心!機能ごとのモジュール
7 ├── hooks # アプリ全体で使う共有フック
8 ├── lib # サードパーティライブラリの設定(Axios, React Queryなど)
9 ├── stores # グローバルステート(必要な場合のみ)
10 ├── testing # テストユーティリティ
11 ├── types # 共有の型定義
12 └── utils # 共有のユーティリティ関数
ここまでは一般的かもしれませんが、重要なのは `features` フォルダです。
2. Feature(機能)ベースの構造とは?
従来の「レイヤーベース(componentsフォルダに全てのコンポーネントを入れ、hooksに全てのフックを入れる)」だと、機能が増えるにつれて関連ファイルが分散し、修正
が大変になります。
Bulletproof React では、1つの機能に必要なものをすべて1つのフォルダにまとめます(Colocation)。
例えば、「ディスカッション機能 (discussions)」という機能がある場合、以下のような構造になります。
1 src/features/discussions
2 ├── api # この機能専用のAPI定義
3 ├── components # この機能でしか使わないコンポーネント
4 ├── hooks # この機能専用のフック
5 ├── routes # この機能に関連するルート定義
6 ├── stores # この機能専用の状態管理
7 ├── types # この機能専用の型
8 └── utils # この機能専用の関数
メリット:
* 凝集度が高い: その機能を修正する際、このフォルダを見るだけで完結します。
* 削除が容易: 機能が不要になったら、フォルダごと削除すればOKです。
3. 重要なルール:単方向の依存関係
このアーキテクチャを成功させるために、「インポートの方向」に厳格なルールを設けています。
1. Shared -> Features -> App の一方向に依存する。
* src/components (Shared) は、src/features をインポートしてはいけない。
* src/app は、src/features や src/components をインポートして組み立てる。
2. Feature間のインポート禁止
* 例えば、features/users が features/discussions を直接インポートするのはNGです。
* もし機能間で共有したいロジックがあれば、それは src/hooks や src/components などの「共有フォルダ」に移動させるべきサインです。
これにより、機能同士が密結合になる(スパゲッティ化する)のを防ぎます。リポジトリ内では、これを ESLint (import/no-restricted-paths)
で強制する方法も紹介されています。
---
ここまでで、プロジェクト構造についてイメージは湧きましたでしょうか?
「こういうケースはどうするの?」といった疑問があれば、さらに深掘りします。
かなりわかりやすいですね。深堀り質問をして理解を深めていきましょう。
> 単方向の依存関係について、もう少し深堀り説明をしてほしいです。
✦ 承知いたしました。「単方向の依存関係 (Unidirectional Codebase Architecture)」について、なぜそれが重要なのか、具体的にどう制御するのかを深掘りします。
このルールは、大規模なReactアプリが「保守不可能な巨大な泥団子 (Big Ball of Mud)」になるのを防ぐための防波堤です。
1. 依存関係の階層モデル
このアーキテクチャでは、コードを3つのレイヤー(階層)に分けて考えます。上から下へは依存(インポート)してOKですが、下から上への逆流は禁止です。
1 [ レイヤー 1: アプリケーション層 (App) ]
2 ↑ (import OK)
3 [ レイヤー 2: 機能層 (Features) ]
4 ↑ (import OK)
5 [ レイヤー 3: 共有層 (Shared) ]
各レイヤーの役割とルールの詳細
1. Shared層 (`components`, `hooks`, `lib`, `utils` など)
* 役割: アプリ全体で汎用的に使える部品。特定のビジネスロジック(機能)を知りません。
* ルール: features や app の中のコードをインポートしてはいけません。
* 例: Button コンポーネントが、特定の UserList 機能を知っているのはおかしいですよね。
2. Features層 (`features/users`, `features/discussions` など)
* 役割: 特定のドメイン(業務領域)に関するロジックやUI。
* ルール:
* Shared 層を使うのはOK。
* 重要: 他の `Feature` をインポートしてはいけません。(水平方向の依存禁止)
* App 層をインポートしてはいけません(逆流禁止)。
* 例: features/auth(認証機能)の中で、features/discussions(掲示板機能)のコンポーネントを直接呼ぶのは避けます。
3. App層 (`app`, `pages`, `routes`)
* 役割: アプリ全体の組み立て。ページ定義、ルーティング設定、プロバイダー設定。
* ルール: すべての層 (Features, Shared) をインポートしてOK。ここで部品を組み合わせてページを作ります。
---
2. なぜ「Feature間の依存(水平方向)」を禁止するのか?
例えば、features/users(ユーザー機能)と features/posts(投稿機能)があるとします。
* 悪い例: posts のコンポーネント内で import { UserAvatar } from '../users' と書いてしまう。
* これを行うと、posts 機能を使いたいだけなのに users 機能もセットで付いてきます。
* 依存関係が網の目のようになり(AがBを呼び、BがCを呼び、CがAを呼ぶ...)、循環参照エラーの原因になります。
* ある機能を修正したときの「影響範囲」が予測不能になります。
* 解決策: 共有すべきものは Shared に移動する。
* UserAvatar が汎用的なら、src/components/ui/Avatar に移動させる。
* あるいは、App 層で組み合わせて渡す。
3. 具体的な ESLint での強制方法
口頭のルールだけでは守られないため、このリポジトリでは eslint-plugin-import の no-restricted-paths ルールを使って機械的に禁止しています。
.eslintrc.cjs の設定イメージ(リポジトリ内の設定を簡略化したもの):
1 rules: {
2 'import/no-restricted-paths': [
3 'error',
4 {
5 zones: [
6 // 1. Shared層を守る: Shared層が Features や App をインポートするのを禁止
7 {
8 target: './src/components',
9 from: ['./src/features', './src/app']
10 },
11
12 // 2. Feature間の独立性を守る: features/auth が他の feature をインポートするのを禁止
13 {
14 target: './src/features/auth',
15 from: './src/features',
16 except: ['./auth'] // 自分自身はOK
17 },
18 // (他のfeatureについても同様に設定...)
19
20 // 3. App層への逆流を防ぐ: Features が App をインポートするのを禁止
21 {
22 target: './src/features',
23 from: './src/app'
24 }
25 ]
26 }
27 ]
28 }
このように設定しておくと、ルール違反のインポートを書いた瞬間にエディタでエラーが出るため、開発者は自然と正しいアーキテクチャに従うようになります。
NotebookLM を使ってチームで質問を共有
プロジェクトはチームで進めることが多いため、あるメンバーの質問は別のメンバーにとっても有益な情報になります。Gitingest で作成したリポジトリ情報のテキストを NotebookLM にアップロードしておくと、チーム全体で質問と回答を共有可能です。
NotebookLM 上で質問を入力すると、アップロードされたリポジトリ情報に基づいて生成AIが回答します。こうすることで、個人が調べた内容や壁打ち結果をチームで再利用でき、同じ質問を何度も繰り返さずに済みます。
おわりに
本記事では、生成AI時代におけるコードリーディングの考え方を解説しました。鍵になるのは、生成AIが読みやすい形に情報を整えて渡すことです。適切に準備さえできていれば、生成AIはリポジトリ全体の理解を圧倒的に早める強力なパートナーになります。
2025年を振り返ると、要件定義・設計・開発・テスト・運用と、システム開発のあらゆるプロセスで従来のやり方を見直し続けた一年でした。変わるものと変わらないものを見極めながら、これからも技を磨き続けていきたいと思います。


