on Rails なフロントエンドコンポーネント指向開発(発表資料)


はじめに

自己紹介

  • 株式会社ユニークビジョン所属
  • 前職は社内 SE → Web アプリ開発
  • 転職時に Ruby on Rail を中心に Web 系の技術を習得
  • 普段の仕事では Vue.js メイン

今日話すこと


フロントエンド開発で得た知見を Rails での開発に活かせないか?


フロントエンドをコンポーネント指向で開発できたら良いなあ...


でも rail 🛤には乗っていたい。ActionView をフル活用したい。


on Rails なフロントエンドコンポーネント指向開発がしたい


どうやって?

  • CSS を可能な限り書かない → Tailwind on Rails
  • views / components / FormHelper の3レイヤーで考える

Tailwind on Rails


Tailwind CSS

  • 最近流行っている CSS ライブラリ
  • CSS をクラスで指定できる
  • CSS の 99% は置き換え可能(体感値)
  • CSS 管理からの解放
  • スタイルを html 上で表現できる!

CSS を書かざるを得ないとき

app/views/users/show.html.erb
<div data-scope-path="users/show">
  <div class="user-name">
    <%= @user.name %>
  </div>
</div>
app/assets/stylesheets/scopes/users/show.scss
[data-scope-path="users/show"] {
  .user-name {
    // ここに書いた CSS は users/show.html.erb のみに適用される
  }
}

views / components / FormHelper の3レイヤーで考える


Atomic Design


Rails における対応

  • FormHelper *
    • text_field options_for_select など
  • View Components *
    • react にインスパイアされて誕生した Rails 謹製のコンポーネントインターフェース
  • views/
    • views/users/show.html.erb のような従来の views ディレクトリ内のページファイル

View Components

  • 従来のパーシャルに近い
  • パーシャルをコンポーネント志向の文脈で再解釈・拡張したもの
  • セットアップ方法

View Components

  • rails コマンドで作成
bin/rails generate component Example title
  • 下記のようなファイルができる
components/example_component.rb
class ExampleComponent < ViewComponent::Base
  def initialize(title:)
    @title = title
  end

  # このコンポーネント関連のメソッドを自由に定義できる
end
components/example_component.html.erb
<!-- example_component.rb のメソッドを自由に使える -->
<span title="<%= @title %>"><%= content %></span>
  • コンポーネントを呼び出す時
views/home/index.html.erb
<%= render(ExampleComponent.new(title: "my title")) do %>
  Hello, World!
<% end %>

FormHelper

label(:article, :title)
# => <label for="article_title">Title</label>

text_field(:article, :title)
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" />
  • これ自体が既に Atoms に相当するコンポーネント
  • 便利なインターフェース
  • ただしスタイルは含まれない
  • tailwind でスタイルを毎回正確に付けるのは大変
  • スタイルを上手く管理できれば完全な存在に

FormHelper のスタイル問題

どうするか

  • グローバル CSS で要素ごとにスタイル定義

なぜ? scoped が良いのでは?

  • 末端要素のスタイルはプロジェクト全体で共有する必要がある
  • 基本的な HTML 要素は数が限られているため、管理の手間が爆発的に増えることはない。

注意点

  • クラス指定のみ!
  • 要素指定だと、意図しない要素にまでスタイルがついてしまう。

Tailwind で書いてみた例

application.scss
.btn {
  @apply rounded p-1 cursor-pointer;
}

.btn-white {
  @apply btn bg-white;
}

.btn-outline-blue {
  @apply bg-white border border-blue-500 border-solid;
}

.textarea {
  @apply border border-blue-500 border-solid rounded;
}


時間があればデモ


まとめ

  • Rails も少し見方を変えるだけでコンポーネント指向的開発ができそう
  • Tailwind で CSS を駆逐しよう
  • どうしても CSS を使いたいときは Scoped に書こう
  • グローバルな CSS は 基本的な HTML 要素に限り使用可
  • ViewComponent を使っていこう