今回はRailsアプリケーションで使用されるERBテンプレート(Embedded Rubyテンプレート)の静的解析ツールである「erb_lint」とRuboCopの連携方法についてまとめてみました。RuboCop単体だけではチェックできないERBのスタイルもチェックしてくれるようになるので、ERBを多く使っているプロダクトでは役に立ちそうなツールです。
erb_lintとは
erb_lintはRailsアプリケーションで使用されるERBテンプレート(Embedded Rubyテンプレート)の静的解析ツールです。erb_lintを使用することで、ERBテンプレートの慣例やベストプラクティスに違反する箇所を警告またはエラーとして検出することができます。これにより、コード品質の向上、保守性の向上、バグの予防などに役立ちます。
また、RuboCopのようにチェックだけでなく自動修正機能(コマンドは以下)も備わっているため簡単な違反であれば素早く対応することができます。
% bundle exec erblint --lint-all -a
erb_lintの導入と使い方
新規アプリケーションの作成
% rails new erb-lint-sample -d mysql
% cd erb-lint-sample
% rails db:create
- Ruby: 3.2.2
- Rails: 7.0.6
- DB: MySQL
erb_lintの導入
# Gemfile
group :development do
gem 'erb_lint', require: false
end
% bundle install
erb_lintの動作確認
以下のコマンドでerbのチェックと自動修正を実行することができます。
# ERBのLintチェック
% bundle exec erblint --lint-all
# ERBのLintチェックと自動修正
% bundle exec erblint --lint-all -a
試しに以下のように、application.html.erb
のtitleタグの閉じタグである「>」を消してerb_lintを実行してみます。(この場合は自動修正は適用されないので、手動で修正する必要があります。)
# app/views/layouts/application.html.erb
- <title>ErbLintSample</title>
+ <title>ErbLintSample</title
% bundle exec erblint --lint-all
Linting 2 files with 14 linters...
expected whitespace, '>', attribute name or value (at <)
In file: app/views/layouts/application.html.erb:5
expected whitespace, '>', attribute name or value (at m)
In file: app/views/layouts/application.html.erb:5
Non-whitespace character(s) detected: "<".
In file: app/views/layouts/application.html.erb:4
3 error(s) were found in ERB files
RuboCopとの連携
続いてRuboCopとerb_lintを連携していきます。
参考: RuboCop
RuboCopの導入
# Gemfile
group :development, :test do
gem 'rubocop'
gem 'rubocop-performance'
gem 'rubocop-rails'
end
% bundle install
RuboCop設定ファイルの生成と編集
RuboCopの設定ファイルである.rubocop.yml
を生成します。
% touch .rubocop.yml
# .rubocop.yml
require:
- rubocop-performance
- rubocop-rails
AllCops:
NewCops: enable
erb_lint設定ファイルの生成と編集
erb_lintの設定ファイルである.erb-lint.yml
を生成します。
% touch .erb-lint.yml
exclude:
- '**/vendor/**/*'
- '**/node_modules/**/*'
EnableDefaultLinters: true
linters:
Rubocop:
enabled: true
rubocop_config:
inherit_from:
- .rubocop.yml
ただ上記の記述で自動修正を実行すると、以下のようにスタイルが崩れてしまいます。
% bundle exec erblint --lint-all -a
<!DOCTYPE html>
<html>
<head>
<title>ErbLintSample</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
# frozen_string_literal: true
csrf_meta_tags
%>
# frozen_string_literal: true
csp_meta_tag
%>
# frozen_string_literal: true
stylesheet_link_tag 'application', 'data-turbo-track': 'reload'
%>
# frozen_string_literal: true
javascript_importmap_tags
%>
</head>
<body>
# frozen_string_literal: true
yield
%>
</body>
</html>
そのため以下のようにEnabled: false
を設定し、やりすぎないように修正します。これにより、いい感じに自動修正が反映されるはずです。
exclude:
- '**/vendor/**/*'
- '**/node_modules/**/*'
EnableDefaultLinters: true
linters:
Rubocop:
enabled: true
rubocop_config:
inherit_from:
- .rubocop.yml
Style/FrozenStringLiteralComment:
Enabled: false
Layout/InitialIndentation:
Enabled: false
Layout/TrailingEmptyLines:
Enabled: false
% bundle exec erblint --lint-all -a
個人的に微妙なポイント
erb_lintには以下のようにインデントを自動修正してくれることを一番期待していました。しかしここまではやってくれなそう、、、(こうすればできるよ!等あればコメントで教えていただきたいです。)
<!DOCTYPE html>
<html>
<head>
<title>ErbLintSample</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', 'data-turbo-track': 'reload' %>
<%= javascript_importmap_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
↓ 以下のようにインデントを自動修正してほしい
<!DOCTYPE html>
<html>
<head>
<title>ErbLintSample</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "zdata-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
まとめ
- erb_lintはRailsアプリケーションで使用されるERBテンプレート(Embedded Rubyテンプレート)の静的解析ツールのこと
bundle exec erblint --lint-all -a
でerbの自動修正を実行することができる.erb-lint.yml
で設定を加えることができる- インデントを自動修正まではできない???
参考
今回はRailsアプリケーションで使用されるERBテンプレート(Embedded Rubyテンプレート)の静的解析ツールである「erb_lint」とRuboCopを連携して使う方法について紹介しました。コードの品質を向上させることができるのでerbを使っているプロダクトではぜひ取り入れてみてください。