Laravel9でLarastan + Laravel Pintを使ってみる

# はじめに
この記事は`Larastan`と`Laravel Pint`の設定方法や使い方について書いています。

以下を参考にしています。

https://github.com/nunomaduro/larastan

https://phpstan.org/user-guide/getting-started

https://readouble.com/laravel/9.x/ja/pint.html

# 対象者
`Larastan`、`Laravel Pint`について知りたい方、Laravelプロジェクトで使用する`Linter`、`Formatter`を検討中の方を対象としています。

また、Laravel9の環境構築ができている前提で進めます。

# 記事の流れ
**Larastanについて**
[larastanとは](#larastanとは)
[1.インストール](#1-インストール)
[2.設定ファイルを作成編集](#2-設定ファイルを作成編集)
[3.静的解析を実行](#3-静的解析を実行)

**Laravel Pintについて**
[Laravel Pintとは](#laravel-pintとは)
[1.インストール](#1-インストール-1)
[2.Laravel Pint実行](#2-laravel-pint実行)
[3.ルールを追加する](#3-ルールを追加する)

# 環境
* Laravel：9.24.0
* PHP：8.1.13

# Larastanとは
`Larastan`は静的解析ツールで`PHPStan`のラッパーです。
デフォルトでLaravel用の固有ルールが定義されていて、複雑な設定などせずに使えます。

Laravelの固有ルールについては下記に記載されています。

https://github.com/nunomaduro/larastan/blob/master/docs/rules.md

早速導入手順を説明していきます。

# 1. インストール
まずはインストールします。
`Laravel`は9.0以上、`PHP`は8.0以上である必要があります。
```sh
composer require nunomaduro/larastan:^2.0 --dev
```

# 2. 設定ファイルを作成・編集
Laravelのルートディレクトリに`phpstan.neon`というファイルを作成し、編集します。
```phpstan.neon
includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:

    paths:
        - app/

    # Level 9 is the highest level
    level: 5

#    ignoreErrors:
#        - '#PHPDoc tag @var#'
#
#    excludePaths:
#        - ./*/*/FileToBeExcluded.php
#
#    checkMissingIterableValueType: false
```

`parameters`内にある各パラメータについて説明していきますが、`paths`と`level`以外は頭の片隅に入れて置く程度で良いと思います。

### paths
解析する範囲を指定するためのパラメータです。
`app/`配下のファイルを解析したい場合は下記のようにします。
```phpstan.neon
paths:
    - app/
```

### level
適用するルールを設定するためパラメータです。
設定できる`level`は`0〜9`まであり、数字が大きくなるほどルールが厳しくなります。
チームでコードの書き方を合わせたいくらいなら、あまり厳しくしないでも良いと思います。

各`level`ごとのルールについて詳しく知りたい方は下記を確認してみてください。

https://phpstan.org/user-guide/rule-levels

### ignoreErrors
解析した際、特定のエラーを発生させたくない場合に使用するパラメータです。
例えば`Method Foo\Bar::baz() should return Illuminate\Http\Response but return statement is missing.`のようなエラーが発生した場合には下記のように正規表現を利用してエラーを除外できます。
```phpstan.neon
ignoreErrors:
    - '#Method [a-zA-Z0-9\\:()]* should return Illuminate\\Http\\Response but return statement is missing\.#'
```
また、パスを指定して、特定のディレクトリやファイルのみエラーを除外することもできます。
```phpstan.neon
ignoreErrors:
    -
        message: '#Method [a-zA-Z0-9\\:()]* should return Illuminate\\Http\\Response but return statement is missing\.#'
        path: Foo\Bar
```

https://phpstan.org/user-guide/ignoring-errors

### excludePaths
解析から除外するディレクトリ、ファイルを設定するためのパラメータです。
例えば`Controllers`配下を除外するには下記のように指定します。
```phpstan.neon
parameters:
    excludePaths:
        - app/Http/Controllers
```

https://phpstan.org/user-guide/ignoring-errors#excluding-whole-files

### checkMissingIterableValueType
**曖昧な型宣言**を許容する際に使用するパラメータです。
`level`を5以下に設定している場合は型宣言のエラーは発生しないので触る必要はありません。

https://phpstan.org/config-reference#vague-typehints

下記のように設定します。
```phpstan.neon
parameters:
    checkMissingIterableValueType: false
```

ちなみに**曖昧な型宣言**ですが、下記の1つ目例のように配列内の値の型が宣言されていない状態のことを指します。

:::note alert
配列内の値の型が不明確で曖昧な型宣言になっている
```php
function foo(array $bar) {
    //
}
```
:::

:::note info
配列内の値の型が明確で具体的な型宣言になっている
```php
/**
* @param array{ num: int } $bar
*/
function foo(array $bar) {
    //
}
```
:::

# 3. 静的解析を実行
ルートディレクトリで下記コマンドを実行します。
```sh
./vendor/bin/phpstan analyse
```

このままだとコマンドが長いのでエイリアスをつけるといいと思います。
設定方法ですが、`composer.json`ファイルの`scripts`内に下記のようにコードを追加します。

```composer.json
"scripts": {
    "lint": [
        "./vendor/bin/phpstan analyse"
    ]
}

```
下記コマンドで実行できるようになります。
```sh
composer lint
```

これで`Larastan`の設定は完了です。

# Laravel Pintとは
`PHP-CS-Fixer`のラッパーでコードのスタイルを整えてくれるLaravel用の`Formatter`です。

導入がとても簡単で、インストールするだけで使えてしまいます。
また、設定ファイルを作成してルールを追加することもできるので、細かいカスタマイズも可能です。

導入手順を書いていきます。
# 1. インストール
まずはインストールします。
```sh
composer require laravel/pint --dev
```

# 2. Laravel Pint実行
実行します。
```sh
./vendor/bin/pint
```
これだけです。
拍子抜けするくらい簡単ですね。

こちらも`Larastan`と同様にエイリアスを付けるとスマートでいいと思います。
```composer.json
"scripts": {
    "fix": [
        "./vendor/bin/pint"
    ]
}
```

再度実行して見てください。
```sh
composer fix
```

# 3. ルールを追加する
`Laravel Pint`では専用のファイルを作成し、ルールを追加することもできます。
ルートディレクトリに`pint.json`ファイルを作成し、下記のように編集します。
```pint.json
{
  "rules": {
      "method_chaining_indentation": true
  }
}
```
上記のルールはメソッドチェーンのインデントを揃えるためのものです。

ルールが適用されているか確認するために下記のようなコードを書いてみてください。
```php
<?php
$user = User::where('age', '>=', '18')
        ->get();
```
`Laravel Pint`を実行します。
```sh
composer fix
```
下記のようにインデントが入ります。
```php
<?php
$user = User::where('age', '>=', '18')
            ->get(); // インデントが入る
```

他にも色々なルールがありますので気になるものを試してみてください。

https://mlocati.github.io/php-cs-fixer-configurator/#version:3.14

# 最後に
ここまで見ていただき、ありがとうございました。
`Larastan`と`Laravel Pint`は導入が簡単でLaravelのためのルールが元から設定されているため、Laravelを使用するプロジェクトでは候補になりやすいのではないかと思います。

実際に私が技術選定した際も他のライブラリと比較して導入コスト低いこと、元からLaravel用のルールが設定されている点に魅力を感じて採用しました。
Laravelプロジェクトでどのライブラリを使おうか迷っている方はぜひ使ってみてください。


# 参考

https://github.com/nunomaduro/larastan

https://phpstan.org/user-guide/getting-started

https://readouble.com/laravel/9.x/ja/pint.html