🛤️

Rails+Inertia環境でTailwind CSSのビルドを一本化する

に公開

結論

Rails に tailwindcss-rails を入れた状態で Inertia Rails を --vite --tailwind 付きで導入すると、Tailwind CSS のビルドが二系統で並走する。Vite はどのみち必須なので、Tailwind CSS のビルドは Vite 側へ寄せたほうがよい。

セットアップ

Rails アプリに tailwindcss-rails を導入する。

bundle add tailwindcss-rails
bin/rails tailwindcss:install

通常の Rails ビュー側の動作確認用に /users を用意する。

bin/rails generate scaffold User name:string
rake db:migrate

続いて Inertia Rails を Vite + TypeScript + React + Tailwind CSS 付きで導入する。

bundle add inertia_rails
VITE_RUBY_PACKAGE_MANAGER=pnpm rails generate inertia:install --package-manager=pnpm --vite --typescript --framework=react --tailwind --force --verbose
bin/dev

この状態で /users/inertia-example の両方が表示できる。共存自体は問題なく成立する。

問題点

共存はできるが、裏では Tailwind CSS のビルドが二系統で走っている。

  1. app/assets/tailwind/application.css を入口とする tailwindcss-ruby
  2. app/frontend/entrypoints/application.css を入口とする Vite 側の Tailwind CSS

Tailwind CSS は使われているクラスをテンプレートから走査して収集するため、ビルド経路が二つあると、監視対象・設定ファイル・生成 CSS のすべてが二重化する。

解決策

Vite 側に集約する。tailwindcss-ruby を止めるだけだと Rails の ERB が監視対象から外れるので、Vite 側で ERB を見るようにする。

Procfile.dev から css: 行を削除して tailwindcss-ruby を停止する。

ruby -i -e 'puts ARGF.read.gsub(/^css:.*\R?/, "")' Procfile.dev

Tailwind CSS v4 の @source ディレクティブで ERB と helper を監視対象に追加する。

cat <<'EOF' >> app/frontend/entrypoints/application.css
@source "../../views/**/*.html.erb";
@source "../../helpers/**/*.rb";
EOF

tailwindcss-rails は不要なので削除する。

bundle remove tailwindcss-rails
rm -rf app/assets/tailwind

検証用スクリプト

開く
setup.sh
#!/bin/sh -ve
ruby -v
rails -v
pnpm -v
node -v
gem list tailwindcss-rails

rm -fr my_app
rails new my_app --skip-js
cd my_app

bundle add tailwindcss-rails
bin/rails tailwindcss:install

bin/rails generate scaffold User name:string
rake db:migrate

bundle add inertia_rails
VITE_RUBY_PACKAGE_MANAGER=pnpm rails generate inertia:install --package-manager=pnpm --vite --typescript --framework=react --tailwind --force --verbose

cat <<'EOF' > app/frontend/pages/inertia_example/index.tsx
export default function App() {
  return <p className="text-9xl font-extrabold">Inertia Rails</p>
}
EOF

ruby -i -e 'puts ARGF.read.gsub(/^css:.*\R?/, "")' Procfile.dev

cat <<'EOF' >> app/frontend/entrypoints/application.css
@source "../../views/**/*.html.erb";
@source "../../helpers/**/*.rb";
EOF

bundle remove tailwindcss-rails
rm -rf app/assets/tailwind

open http://localhost:3000/
open http://localhost:3000/users
bin/dev

補足: 逆方向に寄せることもできる

Rails の通常ビューが中心のアプリであれば、Vite 側の Tailwind CSS プラグインを外して tailwindcss-ruby に寄せてもよい。tailwindcss-rubyapp/frontend 配下まで既定で見ているため、これだけで Inertia 側のクラスも拾える。ただし Inertia/React を使う以上 Vite はいずれにせよ起動するので、プロセス数の節約にはならない。

Discussion