Prettier for Ruby を使ってみる

PrettierRuby 向けプラグインがあったので試してみることにした。

github.com

インストールと使い方

gem もしくは npm でインストールできるらしいが、今回は gem でインストールすることにした。

gem 'prettier'

インストールしたら以下のコマンドで実行できる。

# フォーマット結果の確認
bundle exec rbprettier --check '**/*'

# フォーマットして上書き保存する
bundle exec rbprettier --write '**/*'

ただ、このままだと node_modulesvendor/bundle の中までフォーマットしてしまうので、.prettierignore を作って除外ファイルを指定したほうがよい。
また、slim や yaml があると「対応する Parser が無い」というエラーが出るが、コマンド実行時のターゲットを '**/*.rb' とすることで回避できる。 (ここらへんは rbprettier 側でよしなにやってほしい気がするが…)

RuboCop と一緒に使う

RuboCop で Layout や Style のルールを有効にしている場合は、Prettier と衝突するルールを disable しておく必要がある。

Prettier for Ruby では、そういったルールを disable するための設定ファイルが提供されており、rubocop.yml に以下のように書くことで include できる。

inherit_gem:
  prettier: rubocop.yml

この点は eslint-config-prettier みたいな感じで良いなと思った。

フォーマット結果を見てみる

雰囲気を味わえるように、個人の Rails アプリに Prettier を適用した結果をいくつか載せてみる。

   private

-    def check_permission
-      render_not_found unless current_user.admin?
-    end
+  def check_permission
+    render_not_found unless current_user.admin?
+  end
 end

private 以降の追加のインデントはなし。

 class ApplicationController < ActionController::Base
-  before_action :check_aa,     if: :user_signed_in?
-  before_action :check_bbbb,   if: :user_signed_in?
+  before_action :check_aa, if: :user_signed_in?
+  before_action :check_bbbb, if: :user_signed_in?
   before_action :check_cccccc, if: :user_signed_in?

揃えない。代入やコメントも同じスタイルだった。

   def index
-    @battles = current_guild.battles.ordered.page(params[:page]).decorate
+    @battles =
+      current_guild
+        .battles
+        .ordered
+        .page(params[:page])
+        .decorate
   end

メソッドチェーンはいい感じに改行される。
Rails.application.routes.draw とかも改行されてしまうが仕方ない。

   def result_options
     h.options_for_select(
-      Battle.results.map { |k, _v| [Battle.human_attribute_enum(:result, k), k] },
+      Battle.results.map do |k, _v|
+        [Battle.human_attribute_enum(:result, k), k]
+      end,
       selected: result
     )
   end

ブロックは一行が長くなる場合は do ... end になる。

 class User < ApplicationRecord
-  validates :provider, presence: true, uniqueness: { case_sensitive: true, scope: :uid }
-  validates :uid,      presence: true
+  validates :provider,
+            presence: true,
+            uniqueness: {
+              case_sensitive: true,
+              scope: :uid
+            }
+  validates :uid, presence: true
 end

いい感じ。

あと、文字列リテラルにはシングルクォートを使うようになっていた。
他にもいろいろあるので、気になる方は手元で適用してみてほしい。

VSCode で保存時に自動的にフォーマットする

VSCode 用の Prettier 拡張機能として prettier-vscode があるが、Ruby もこれを使ってフォーマットすることができる。
ただし、インストールしただけでは Prettier が Ruby の Formatter として認識されず、何か設定をする必要があるようだった。
調べてみると Issue にいろいろ方法が書かれていたが、手元で試した結果を言うと @prettier/plugin-ruby を npm/yarn でインストールすればフォーマットできるようになった。

あとは以下の内容で .vscode/settings.json を作っておくだけで保存時に自動フォーマットされる。

{
  "[ruby]": {
    "editor.formatOnSave": true
  },
}

感想

  • Prettier はフロントの開発でしか使ったことがなかったが、プラグインRuby のような言語にも対応できるようになっているのはおもしろいと思った。
  • Opinionated な Formatter はデフォルトの設定がいい感じであってほしいが、その点 Prettier for Ruby は個人的には違和感なかった。
  • prettier-vscode で保存時に自動でフォーマットしてくれるのは便利。