🐥

VS Code(Cursor)にてLaravelのbladeファイルのフォーマッタが効かない問題を解消

2024/04/14に公開

はじめに

以前よりVS Code(Cursor)Laravelのbladeファイルのフォーマットがいまいちで不満はあったですが、時間も確保できず何となくで開発を進めていたのですが、開発メンバーが増えたこともあり、ちゃんとしなくてはと、設定周りを改めて調べてみました。

結論としては、一部不十分ではありますが、普通に設定項目があり、ほぼ一撃解決でした。

拡張機能をインストール

フォーマッタは拡張機能として提供されているので、必要なものをインストールします。

PHP Intelephense・・・PHPのフォーマッタとコードスニペット用
Laravel Extension Pack・・・以下13個の拡張機能のセットです。とりあえず入れておきましょう。
Laravel ArtisanLaravel Create ViewDevDbなどは正直使ったことがなく、
このブログを書く上で初めて利用したのですが、意外と便利そうです。
また、個別に入れていくより楽なので、Extension Packでインストールするのが楽です。

  • Laravel Extension Packに含まれる拡張機能一覧
    拡張機能 目的
    Laravel Blade Snippets Laravelブレードのスニペットとシンタックスハイライトのサポート
    Laravel Snippets Laravelスニペット
    Laravel Artisan Laravel Artisan
    Laravel Extra Intellisense Laravel IntelliSenseの拡張
    Laravel goto view Controllerで実装したView等のドット記法で書いたbladeファイル指定からbladeファイルへ定義ジャンプができるようになります。
    laravel-jump-controller ルートファイルのRoute定義からコントローラーファイルへ定義ジャンプできるようになります。
    laravel-goto-components layoutファイルなどのextendsやincludeの指定から該当のコンポーネント化したbladeファイルを開けます。
    Laravel Blade formatter Bladeのフォーマッター
    Laravel Create View ドット記法を使用したLaravelビューの作成
    Laravel Blade Wrapper Bladeディレクティブをラップする拡張機能
    DotENV .env構文の強調表示
    DevDb データベースを自動的にロードし、IDEの中にデータを表示するゼロコンフィグの拡張機能
    EditorConfig for VS Code EditorConfigは、異なるエディターやIDEで一貫したコーディングスタイルを定義し、維持するのを支援します。

フォーマッタの設定

拡張機能をインストールしただけではbladeのフォーマットが効きません。
設定を追加していきます。

  1. 設定を開く
    上部のメニューから、ファイル>ユーザ設定>設定 で開きます。
    ショートカットキー覚えておくと開くのが便利です。
    Windows:「Ctrl+,」
    Mac:「Cmd+,」

  2. 拡張機能の設定を変更
    設定を開くと、左側にカテゴリが並んでいるので、「拡張機能」の部分を開きます。
    以下の2つの設定を変更します。
    Blade Configuration
    Blade Formatter

  3. Blade Configuration
    「Enable format blade file」という1つしか設定項目がありません。
    これはLaravel Blade Snippets拡張機能のフォーマッタを有効化/無効化するための設定です。
    インストール直後はチェックが付いていないはずですが、万が一チェックが付いている場合はチェックを外します。
    次に説明するLalavel Blade Formatter拡張機能のフォーマットを優先的に使用するためです。
    Lalavel Blade Snippetsのフォーマットを使用すると、@ifなどのBladeディレクティブの内側がインデントされないため、ネストした構造になるとコードの視認性が悪くなってしまうからです。
    そのため、Laravel Blade Formatterのフォーマッタ機能を使う方が適切です。

  4. Blade Formatter
    こちら設定がLalavel Blade Formatter拡張機能のフォーマッタ指定となっています。
    こちらはbladeがフォーマットされる際にどのようにフォーマットするかを細かく指定できる設定項目です。

    • Blade Formatter > Format:
      いくつも設定がありますが、とりあえず設定したいのは以下3つ
    オプション 説明 おすすめ設定
    Enabled bladeのフォーマットを有効化するかどうか チェック付けて有効に
    Indent Size インデントのスペースサイズ 通常2 か 4。 個人的には2
    UseTabs インデントにタブを使用するか 私はスペース派なのでチェックなし
    • その他の Blade Formatter > Format:
    オプション 説明 おすすめ設定
    Custom HTML Attributes Order HTMLの属性の順序をカスタマイズ。id,class,nameなどとカンマ区切りで指定することで、その順番でHTMLタグの属性を並び替えてくれます。この設定を有効にするには、下で解説しているSort HTML Attributesのオプションをcustomにする必要があります。 設定なし
    Indent Inner HTML <head>や<body>などの<html>タグ直下のをインデントするかどうか。傾向的にインデントしない方が多い印象。 チェックなし
    No Multiple Emplty Lines 複数の空行をなくす。人間的な資格としてコンテンツの区切りに2行以上の改行入れたりしますが、それが1行になります。お好みで。 チェックあり
    No PHP Syntax Check PHPの構文チェックを無効化 チェックなし
    No Single Quote シングルクオートを使用しないよう設定 チェックあり
    Sort HTML Attributes 指定された規則に沿ってHTML属性をソート。
    none:設定しない
    alphabetical:アルファベット順
    code-guide:コードガイド式※1
    idiomatic:idiomatic-HTML式※2
    vuejs:Vuejs式※3
    custom:カスタム
    code-guide
    Sort Tailwindcss Classes Tailwind CSSクラスをソート Tariwindを使用しているならあり?
    Tariwind未経験なので優位性が不明です。
    Wrap Attributes タグの属性を折り返しするかどうか。
    auto:自動で折り返し
    force:必ず折り返し
    force-aligned:必ず折り返し、属性の開始位置を揃えます。
    force-expand-multilineWrap Attributes Min Attrsで指定した属性の数以上で強制的に折り返し。例えば、数が2の場合、id属性のみであれば折り返さない。id, nameの2属性があれば折り返し
    aligned-multiple:1行の文字数に応じて複数行に折り返し。折り返した位置のインデントは揃えます。折り返しルールはautoと同じ、インデント位置が異なる。
    preserve:現状の折り返し状態を維持します。
    preserve-aligned:現状の折り返し状態を維持しつつ、インデントの位置を揃えます。
    auto
    Wrap Attributes Min Attrs 属性を折り返す最小数。force-expand-multilineを選択時に、指定した個数以上の属性を持つタグは必ず折り返します。 2(折り返し設定によりこの設定は無効なのでデフォルトのまま)
    Wrap Line Length 1行を折り返しする文字数 120(プロジェクトにより調整はアリですが、いくつにしても微妙な折り返しは発生するので基本的にデフォルト採用しておくのが無難です。prettierなどは80文字で折り返しなので80も選択肢としてはアリ)
    • その他のオプション
    オプション 説明 設定
    Misc: Dont Show New Version Message 新バージョンのメッセージを非表示にする 特に困っていないのでチェック無し。

ワークスペース設定を用いてフォーマット設定を共通化

VS Codeの設定でフォーマットができるようになりました。
チーム開発している場合には個人個人で設定を行う必要が出てきます。
設定漏れや誤りがあると、フォーマットが異なることで、意図しない修正が行われてしまう可能性もあります。
フォーマットの設定自体をプロジェクトに含めることでコードを利用するメンバー全員が同じ設定にすることが可能です。

手順

  1. 設定を開く
  2. 設定の「ワークスペース」タブを開く
    設定のページにはタブがあり、「ユーザー」と「ワークスペース」があります。
  3. ワークスペースで必要なオプションを設定
    ワークスペースのタブを選択すると、ユーザーと同じように設定項目が並んでいます。
    ワークスペースのタブで必要なオプションを設定します。
  4. setting.jsonが作成されます。
    オプションを設定するとVS Codeで開いているLaravelプロジェクト直下に.vscodeというフォルダが作成されます。
    そのフォルダの中にsetting.jsonという名前でファイルが作成されており、先ほどワークスペースタブで設定した設定内容がjson形式で書きだされています。
    以下は設定例。
    .vscode/.setting.json
     {
         "[blade]": {
             "editor.defaultFormatter": "shufo.vscode-blade-formatter",
         },
         "bladeFormatter.format.enabled": true,
         "bladeFormatter.format.indentSize": 2,
         "bladeFormatter.format.useTabs": false,
         "bladeFormatter.format.indentInnerHtml": false,
         "bladeFormatter.format.noMultipleEmptyLines": true,
         "bladeFormatter.format.noPhpSyntaxCheck": false,
         "bladeFormatter.format.noSingleQuote": false,
         "bladeFormatter.format.sortHtmlAttributes": "code-guide",
         "bladeFormatter.format.sortTailwindcssClasses": false,
         "bladeFormatter.format.wrapAttributes": "auto",
         "bladeFormatter.format.wrapLineLength": 120,
     }
    
    ※editor.defaultFormatterはフォーマットを指定した際にLalavel Blade Formatterでフォーマットされるように指定しています。
  5. 作成されたsetting.jsonをコード管理に含めます。
    このファイルをgithubなどのコード管理サービス上にプッシュすることで他のメンバーも同じ設定を共有することが可能となります。

拡張機能も推奨事項としてコード管理化する。

拡張機能がインストールされていないとsetting.jsonの設定が有効にならないので、合わせて拡張機能のインストールを促してくれる設定も追加します。

手順

  1. 拡張機能のページを開きます。
  2. アンインストールボタンの右にある歯車アイコンをクリック
  3. 「ワークスペースの推奨事項に追加する」をクリック
  4. extensions.jsonが作成されます。
    setting.json同様.vscodeフォルダに作成されます。
    .vscode/.extensions.json
    {
        "recommendations": [
            "onecentlin.laravel-extension-pack"
        ]
    }
    
  5. コード管理に含めます。

VS Code以外のエディタも使う場合がある、という柔軟な開発体制の場合は、
prettiereditorconfigなどを活用するのが良いでしょう。
prettierについては各種設定オプションについて解説した記事があるので、参考にしてみてください。
https://zenn.dev/rescuenow/articles/c07dd571dfe10f

未解決事項

  • 埋め込み型のjavascriptの記述がフォーマットされない。
    正直実装の問題ではありますが、@yield('script')などとしてレイアウト側でスクリプトの実装を埋め込む定義があり、必要に応じて各ページのbladeが@section('script')でスクリプトの中身を記述していると、該当部分のインデントがかき消され、すべて同じインデントにされてしまいます。

    意図どおりフォーマットされないパターン

    layout.blade.php
    <script type="text/javascript">
        @yield('script')
    </script>
    
    content
    @section('script')
        // jsの実装がいきなり始まる
        $(function() {
            // 処理
        })
    @endsection
    

    意図どおりフォーマットされるパターン
    sectionの中で<script>タグで囲んである実装であればフォーマットされます。

    content
    @section('script')
        <script>
            $(function() {
                // 処理
            })
        </script>
    @endsection
    

    暫定的な解決策としてblade formatterを無効にするようなコメントを記述してフォーマットを回避しています。
    フォーマットして欲しくない箇所を以下のコメントで囲むことで、フォーマットされないようにできます。

    {{-- blade-formatter-disable --}}
    フォーマットして欲しくないコード
    {{-- blade-formatter-enable --}}
    
  • blade内のjavascriptのインデントもbladeと同様になる。
    bladeファイルのインデントをスペース2つにしていると、blade内のjavascript実装も同じインデントになります。気になるようであれば、先ほどのようにフォーマット除外対応するか、スクリプト部分をjsファイルとして切り出すことで対応可能です。

  • ブロックコメントにはフォーマットが適用されない。
    1行コメントは他のコードに合わせて適切にインデントされますが、
    複数行をまとめてコメント化したブロックコメントの場合、フォーマッタが反応しません。

    <!--[if lt IE 9]>
          <script src="https://xxx.js"></script>
          <script src="https://xxx.min.js"></script>
          <![endif]-->
    
    <script>
      /*
          コメント
                コメント
      */
    </script>
    

まとめ

VS CodeでLaravelアプリケーションを開発する際のフォーマッタ指定について解説しました。

注釈

※1・・・以下URLに定義されているコードガイドの属性順に従います。
https://codeguide.co/#attribute-order
以下の順のようです。
1. class
2. id, name
3. data-*
4. src, for, type, href, value
5. title, alt
6. role, aria-*
7. tabindex
8. style

**コードガイドの日本語版**
http://kia-king.com/code-guide/

コードガイドは属性の並び順以外にもHTML、CSS記述の際の原則的なことが書いてあり、守っておいて損はない事ばかりでした。それほど文章量も多くないため一読おすすめします。

※2・・・以下Githubにて定義されているHTML開発のガイドにある属性の順序に従います。
https://github.com/necolas/idiomatic-html#attribute-order
1. class
2. id
3. data-*
4. その他すべて
コードガイドの簡易版といった印象です。新たに設定するのであれば、こちらよりコードガイドを定期要するのが良いでしょう。

※3・・・JavascriptのlinterであるeslintのVue版にカスタマイズされた定義
https://eslint.vuejs.org/rules/attributes-order.html
主にVue用のタグ属性の順序について定義されているため、Vueを使っていない場合はあえて選択する意味はないです。

Discussion