Gitコミット時に自動チェック！HuskyでESLint・PHPStan・ユニットテストを効率化する方法

# 概要
Gitフックを活用して、ESLint、PHPStan、ユニットテストを自動的に実行することで、手動作業を減らし、コード品質を保つ方法を解説します。本記事では、Huskyを使った設定手順を紹介し、効率的なチーム開発を実現します。コミット前に自動でチェックを行い、エラーを未然に防ぐフローを構築します。

# 目的

この記事の目的は、**Gitコミット時に静的解析やテストを自動実行し、コード品質を確保する仕組みを構築すること**です。これにより、以下を実現します：

1. **コミット時のエラー防止**  
   - ESLint（JavaScript/TypeScriptの静的解析）、PHPStan（PHPの静的解析）、ユニットテストをコミット時に自動実行し、不備があればコミットを防止します。
   - チーム全体でコード品質を統一し、コードレビューや修正の負担を軽減します。

2. **静的解析とテストのルール遵守**  
   - 開発者が静的解析ツールやテストを意図的に無視するのを防ぎ、ルールの徹底を図ります。

3. **効率的なチーム開発の実現**  
   - 自動チェックの仕組みを導入することで、手動でのチェックが不要になり、効率的な開発フローを確立します。



# 前提条件

この記事を進めるにあたり、以下の条件を満たしていることを確認してください：

1. **静的解析ツールが設定済みであること**
   - 前回の記事を参考に、以下のツールをプロジェクトに導入済みであること：
     - **PHPStan**（またはLarastan）
     - **ESLint**
     - **TypeScript**

2. **ユニットテストが設定済みであること**
   - Laravelのテストフレームワークを使用してユニットテストが実行できる環境が整っていること。


3. **前回までの設定が完了していること**
    - 以下のシリーズ記事を参考にし、PHPプロジェクトや環境構築が済んでいること：
     - [Laravel + Vue3 チーム開発を効率化！統一環境構築と品質向上の完全ガイド](https://qiita.com/ukei2021/items/4b2f047c72dd17c571c7)
     - [DockerでPHP 8.4/Nginx + Node 22 + MySQL環境を構築する方法](https://qiita.com/ukei2021/items/49eb61e4db221346dfe0)
     - [Laravel 11 + Inertia.js + Vue 3 + TypeScriptでモダンなフルスタック環境を構築](https://qiita.com/ukei2021/items/ca36f47975e5fc5ff16e)
     - [Laravel 11 + Vue 3プロジェクトにSassとBootstrap 5を導入する方法](https://qiita.com/ukei2021/items/2a0916ffc9c6ef900cb4)
     - [Laravelでテストコード込みのサービス・リポジトリパターンを実装する方法](https://qiita.com/ukei2021/items/53d3776f580cfd3a074b)
     - [DevContainerを使いVSCodeでPHPStan・ESLint・TypeScriptを統合して静的解析をエラー検知する方法](https://qiita.com/ukei2021/items/d3a91b0a34188529b6f6)


この記事では、これらの前提条件を基に、Huskyを活用して効率的なコードチェックの仕組みを導入する方法を解説します！
 

# 具体的な手順

この記事では、Huskyを導入し、コミット時にESLint、PHPStan、ユニットテストの自動チェックを行う手順を解説します。



## Huskyのインストール

開発コンテナのターミナルで以下のコマンドを実行し、Huskyをインストールします：開発コンテナのターミナルにて
```
$ npm install husky --save-dev
```

### package.jsonの修正
#### **`package.json`**
`prepare`スクリプトに`husky install`を追加します。これにより、Huskyの初期設定が行われます。
```package.json
{
~~~省略~~~
    "scripts": {
        "build": "vite build",
        "dev": "vite",
        "type-check": "vue-tsc --noEmit",
        "prepare": "husky install"
    },
~~~省略~~~
}

```

### pre-commit作成
以下のコマンドを実行して、Huskyのpre-commitフックを作成します：
```
$ npx husky add .husky/pre-commit "npm test"
```
### pre-commitの修正
#### **`.husky/pre-commit`**
コミット時に以下を自動実行する設定を追記します：
- ESLint/TypeScriptのチェック（ステージされたファイルのみ）
- PHPStanの静的解析（ステージされたPHPファイルのみ）
- PHPUnitでのユニットテスト実行（全テストを実行）

以下は、最終的な.husky/pre-commitの内容です：


```sh:pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

export PATH="$HOME/.nvm/versions/node/v22.12.0/bin:$PATH"
npx lint-staged
LINT_STAGED_STATUS=$?

# ステージされた PHP ファイルを取得
STAGED_FILES=$(git diff --cached --name-only --diff-filter=d | awk '/\.php$/')

# Larastan（PHPStan）の静的解析
if [ -n "$STAGED_FILES" ]; then
    echo "Running PHPStan on staged files..."
    vendor/bin/phpstan analyse $STAGED_FILES
    LARASTAN_STATUS=$?
else
    echo "No PHP files staged for PHPStan check."
    LARASTAN_STATUS=0
fi

# PHPUnit のユニットテスト実行
php artisan test
PHPUNIT_STATUS=$?

# 結果を判定
if [ $LINT_STAGED_STATUS -ne 0 ] || [ $LARASTAN_STATUS -ne 0 ] || [ $PHPUNIT_STATUS -ne 0 ]; then
    echo "❌ Pre-commit checks failed. Fix the issues before committing."
    exit 1
fi

echo "✅ All checks passed. Proceeding with commit."
```

この手順に従うことで、Gitコミット時にコードの品質を自動的にチェックし、チーム全体で一貫性のあるコードベースを維持することが可能になります！




# 確認

Huskyの`pre-commit`フックが正しく動作しているかを確認します。以下に各チェックのエラー発生時や成功時の動作を示します。

### **Git操作方法について**

Huskyの`pre-commit`フックは、ターミナルからの`git commit`コマンドだけでなく、**VSCodeのソース管理ビュー（コミットボタン）からのコミット操作にも対応**しています。

- **ソース管理ビューの場所**  
  VSCode左側の「ソース管理」アイコン（もしくは`Ctrl+Shift+G`）をクリックすると、コミット用の入力欄とボタンが表示されます。

- **Huskyの動作**  
  VSCode内でコミットを実行した場合も、`pre-commit`フックが呼び出され、自動チェックが行われます。

以下では、具体的なエラー発生時や成功時の動作を示します。

### **1. TypeScriptエラーがある場合**

以下は、TypeScriptエラーが含まれる状態でコミットを試みた例です：

1. **エラーのあるコード**
   ![TypeScriptエラーの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/37c7c0dd-eb5f-ec68-4881-1f063ec4fe4a.png)

2. **エラーによるコミット拒否**
   ![TypeScriptエラーのチェック結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/d126edd4-1ca3-288d-6cc2-e8f5afee6faa.png)

---

### **2. ESLintエラーがある場合**

次に、ESLintエラーがある場合の挙動を確認します：

1. **エラーのあるコード**
   ![ESLintエラーの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/dc3e04f7-fc3a-87be-58d8-e2d1d763541c.png)

2. **コミット試行時のエラー検知**
   ![ESLintエラーのチェック結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/577ddb79-d51f-7b86-2f19-3ed0eb088851.png)

---

### **3. PHPStanでエラーがある場合**

PHPStan（Larastan）がエラーを検出した場合の例です：

1. **エラーのあるコード**
   ![PHPStanエラーの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/12819efc-b180-ce34-6f04-6049b31e488a.png)

2. **エラーによるコミット拒否**
   ![PHPStanエラーのチェック結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/b8a7846c-4fc3-6365-5f4a-d7f1e65004a0.png)

---

### **4. ユニットテストでエラーがある場合**

ユニットテストが失敗する場合の例です：

1. **意図的に失敗するテストコード**
   ![失敗するユニットテストの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/c250d9b9-b322-341b-fa31-1b01f4d4314a.png)

2. **コミット試行時のエラー検知**
   ![ユニットテストエラーのチェック結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/e7b04346-6d07-c47d-5da7-7fe228564988.png)

---

### **5. 問題がないとき**

すべてのチェックをクリアした場合の例です：

1. **問題がないコード**
   ![正常なコード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/4158b26d-720a-77dd-5098-ed63550e3019.png)

2. **コミット成功**
   ![コミット成功](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/6649b6a8-1b63-e165-29a2-dc0e8180cd03.png)

# まとめ

この記事では、**Gitコミット時に自動チェックを行うHuskyフックの導入方法**を解説しました。以下のポイントを押さえることで、チーム全体でのコード品質管理を効率化できるようになります：

### **Huskyの活用**
- **静的解析とテストの自動実行**  
  コミット時にESLint、TypeScript、PHPStan、ユニットテストを自動的に実行し、不備があればコミットを防止。
- **コミット前に品質を確保**  
  問題が発生したコードがリポジトリに入らない仕組みを構築。

### **チーム開発での利点**
- **統一されたコード品質の実現**  
  各開発者が異なるツールを使うことなく、一貫した開発フローを実現。
- **コードレビューの負担軽減**  
  明確なエラーが事前に検出されるため、レビュー時の指摘を減らし、より重要な部分に集中。

### **VSCodeとの連携**
- VSCodeのコミットボタンからも自動チェックが動作するため、操作がシンプルに。
- 開発環境の統一により、誰でも簡単に使える仕組みを提供。

---

### **この記事を活用することで得られるメリット**
1. **ルール違反や見落としの防止**  
   自動化によって人為的なミスを防ぎ、チーム全体でのルール徹底を実現します。
2. **効率的な開発フロー**  
   コードチェックにかかる時間を削減し、開発スピードを向上させます。




最後に、読んでいただきありがとうございました！

### 関連記事
- [Laravel + Vue3 チーム開発を効率化！統一環境構築と品質向上の完全ガイド](https://qiita.com/ukei2021/items/4b2f047c72dd17c571c7)
- [DockerでPHP 8.4/Nginx + Node 22 + MySQL環境を構築する方法](https://qiita.com/ukei2021/items/49eb61e4db221346dfe0)
- [Laravel 11 + Inertia.js + Vue 3 + TypeScriptでモダンなフルスタック環境を構築](https://qiita.com/ukei2021/items/ca36f47975e5fc5ff16e)
- [Laravel 11 + Vue 3プロジェクトにSassとBootstrap 5を導入する方法](https://qiita.com/ukei2021/items/2a0916ffc9c6ef900cb4)
- [Laravelでテストコード込みのサービス・リポジトリパターンを実装する方法](https://qiita.com/ukei2021/items/53d3776f580cfd3a074b)
- [DevContainerを使いVSCodeでPHPStan・ESLint・TypeScriptを統合して静的解析をエラー検知する方法](https://qiita.com/ukei2021/items/d3a91b0a34188529b6f6)