😽

【Laravel】VSCode上で静的解析とコード整形をしながら開発する環境を整えた

2023/07/13に公開

概要

新規の Laravel アプリケーションを開発するにあたり、

  • 静的解析(Larastan)
  • フォーマッタ(Laravel Pint)

を導入しました。

VSCode で編集&保存後すぐに結果を確認できること(フロントエンド開発 の Eslint,Prettier みたいな形)を目標としました。

やったこと

拡張機能の選定について

静的解析

PHP の静的解析ツールには「Phan、PHPStan、Psalm」などがあります。
最終的な目標は「Laravel の静的解析」なのでそちらから探ったところ、Larastan がデファクトのようでした。

しかし Larastan の VSCode 拡張を探してみたところほとんど存在せず、調べてみたところ以下の issue が PHPStan リポジトリにありました。
https://github.com/nunomaduro/larastan/issues/139

You can use the one for PHPStan and just include larastan's extension.neon into your configuration.

「PHPStan の拡張を Larastan の設定で使えるよ」ってことだったので、PHPStan の拡張機能を導入することにしました。

いくつかの PHPStan 拡張の中で問題なく動作したphpstanを選定しています。

フォーマッタ

コードフォーマッタには Laravel 公式マニュアルにも記載のある Laravel Pint を選定しました。
VSCode の拡張としてこちらもいくつかありますが、Laravel Pintを選定しています。

Dev Container

必要な拡張を必要なプロジェクトのみ導入するため、VSCode 拡張のDev Containerを導入しました。

※Dev Container についてのわかりやすい説明は以下
https://blog.kinto-technologies.com/posts/2022-12-10-VSCodeDevContainer/

.devcontainer を編集し、静的解析などで使用する拡張機能を定義します。

.devcontainer

VSCode から操作するコンテナの定義を行います。

devcontainer.json
{
    "name": "Laravelアプリ",
    "dockerComposeFile": [
        "../compose.yml"
    ],
    "service": "app",
    "workspaceFolder": "/workspace",
    "forwardPorts": [
        9000
    ],
    "customizations": {
        "vscode": {
            "extensions": [
                "open-southeners.laravel-pint",
                "SanderRonde.phpstan-vscode"
            ],
            "settings": {
                "editor.tabSize": 4,
                "editor.formatOnSave": true,
                "editor.defaultFormatter": "open-southeners.laravel-pint",
                "phpstan.binPath": "vendor/bin/phpstan",
                "phpstan.timeout": 1000000,
            }
        }
    },
    "mounts": [
        "source=vendor-store,target=/workspace/vendor,type=volume"
    ]
}

settings へ Dev Container 内での設定を追加

editor.formatOnSave を true とし、editor.defaultFormatter に Laravel Pint 拡張を定義

mounts で名前付きボリュームを定義する

  • 通常、Dev Container 上で PHPStan 拡張を動かそうとするとかなり重くなるため設定(解析に 30 秒ほど)
  • compose.yml での設定も必要(後述)
  • 参考:https://code.visualstudio.com/remote/advancedcontainers/improve-performance
  • この設定をした後はローカルの vendor 以下を削除して Dev Container を立ち上げて確認する
    • VSCode 上で「vendor/bin/phpstan がない」というようなエラーが発生した場合は composer install を実行する
    • composer install によってローカルの vendor 以下にはインストールされない(名前付きボリュームを定義しているため)

phpstan.timeout のデフォルト値(10000)を上げる

mounts を定義してもなお重く、デフォルト値だとタイムアウトしてしまったため(いずれ何とかしたい)

compose.yml

compose.yml
version: '3.8'

volumes:
  vendor-store:

services:
  app:
    volumes:
      - type: bind
        source: ./
        target: /workspace
      - type: volume
        source: vendor-store
        target: /workspace/vendor

.devcontainer の mounts で定義していた source=vendor-store を volumes に定義する

PHPStan 設定

includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:

    paths:
        - app
        - routes

    # Level 9 is the highest level
    # Check type hinting
    level: 6

    parallel:
        maximumNumberOfProcesses: 1

    checkGenericClassInNonGenericObjectType: false

解析レベル

PHPStan では解析のレベルを設定することができます。
今回は新規のプロダクトでなるべく型定義を厳しく設定したいため、Level6 を設定しました。
※level5 以下は型定義を設定しなくても可です。

シングルスレッドで実行

PHPStan はマルチスレッドがデフォルトの設定となっているようです。
スペックが低い場合シングルスレッドの方が効率がよいかも?とのことでこちらを設定しています。
(体感早くなった気もするが、正確に測定はしていないので後で検証したい)
https://lazesoftware.com/ja/blog/230405/

拡張機能が動かない場合


ターミナルを開き、OUTPUT タブを選択します。
右のセレクトボックスから拡張機能を選択するとエラーが吐かれているので、確認すると大抵解決します。
(大体設定ファイルの指定パスが間違ってるとかそんな感じ)

まとめ

まだ運用し始めたばかりのため改善点はあると思いますが、一旦この形で開発していってブラッシュアップしていければと思います。

拡張機能についてですが、基本的に Github スターも少なくメンテもあまりされていないイメージなので、CI 上でのテスト実行の補助的な位置づけで使用できればいいと考えています。

余談ですが、「VSCode 上で Laravel の静的解析をする」みたいな記事が少ないなと感じました。
PHPStorm ではインスペクションとかいう機能で設定できるっぽいですが、PHPer はみんな VSCode を使っていないのかな・・・と感じました。
https://pleiades.io/help/phpstorm/running-inspections.html

調査時に作成したスクラップ

https://zenn.dev/tusi/scraps/b96773894ea5f6
https://zenn.dev/tusi/scraps/474375c4242f33

GitHubで編集を提案

Discussion