Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

cssbundling-rails README(翻訳)

概要

MITライセンスに基づいて翻訳・公開いたします。


  • 2022/09/22: 初版公開
  • 2023/02/02: 更新
  • 2024/01/22: 更新

cssbundling-rails README(翻訳)

cssbundling-rails gemは、Tailwind CSSBootstrapBulmaPostCSS、またはDart Sassを用いてCSSをバンドルおよび処理した後、Railsのアセットパイプライン経由で配信します。このgemは、新しいRailsアプリケーションで上述の好みのバンドラーを利用できるインストーラと、バンドルした出力ファイルをGitなどのソースコード管理に登録されない形でapp/assets/buildsディレクトリに保持する規約を提供します(インストーラはこのディレクトリをデフォルトで.gitignoreに追加します)。

この方法で開発を行うには、ターミナルでyarn build:css --watchを実行してバンドラーをwatchモードで起動しておきます(puma-devなどを使っていない場合は、Railsサーバーを別のターミナルで実行してください)。また、./bin/devを実行すればRailsサーバーとCSSビルドウォッチャーをまとめて起動できます(jsbundling-railsを使っている場合はJavaScriptビルドウォッチャーも起動します)。

このバンドラーがプロジェクトディレクトリ内のスタイルシートファイルの変更を検出するたびに、以下の1を2にバンドルします。

  1. app/assets/stylesheets/application.[bundler].css
  2. app/assets/builds/application.css

これで、<%= stylesheet_link_tag "application" %>と記述する標準的なアセットパイプラインの手法を引き続き用いて、ビルド出力をレイアウト内で参照できるようになります。

アプリケーションをproduction環境にデプロイすると、assets:precompileタスクにcss:buildタスクがアタッチされ(package.jsonにあるすべてのパッケージ依存関係がyarnでインストールされるようにするため)、続いてyarn build:cssを実行してすべてのエントリポイントをdevelopment環境のときと同様に処理します。アセットパイプラインはこの出力を拾い上げてダイジェスト化し、他のアセットパイプラインファイルと同様にpublic/assetsディレクトリにコピーします。

これと同じことが、テストでバンドラーがtest:prepareにアタッチするときにも行われ、テスト開始前にスタイルシートが確実にバンドルされるようになります。テストフレームワークがtest:prepare Rake タスクを呼び出さない場合、テストフレームワークがテスト開始前に css:build を実行してスタイルシートがバンドルされるようにしてください。セットアップでjsbundling-rails(つまりesbuildとtailwind)を利用している場合は、javascript:buildも実行するようにしておく必要があります。

概要は以上です。

バンドラーのオプションは、package.jsonファイル内のbuild:cssスクリプトで設定することも、インストーラが生成するファイルで設定することもできます(Tailwindの場合はtailwind.config.js、PostCSSの場合はpostcss.config.js)。

インストール

システムにnodeとyarnをインストールしておく必要があります。また、npx 7.1.0以降も必要です。

以下を実行します。

  1. ./bin/bundle add cssbundling-railsを実行
  2. ./bin/rails css:install:[tailwind|bootstrap|bulma|postcss|sass]を実行

Rails 7以降は、新規アプリケーション作成時に利用するバンドラーをrails new myapp --css [tailwind|bootstrap|bulma|postcss|sass]のように事前に指定できます。

FAQ

🔗 Q1: tailwindcss-railsやdartsass-railsと比べてどう違いますか?

JavaScriptの処理で既にNodeに依存している場合は、このcssbundling-rails gemを使うことになります。しかしRails 7以降でデフォルトとなったimportmapを使っている場合は、Tailwind CSSやDart Sassをスタンドアロンで利用できるtailwindcss-railsdartsass-railsを使えば、Nodeと一切関わらずに済むようになります。これらはNodeよりもシンプルで可動部品も少なく、それでいてすべての機能を備えています。

🔗 Q2: TailwindでCSSファイルを相対インポートする方法は?

Tailwindのapplication.jsファイル内で @importステートメントを使いたいのであれば、Tailwindでpostcssを使う設定にしてからpostcss-importプラグインを使う必要があります。

しかし、多数のCSSファイルをバンドルして1個の巨大ファイルにする代わりに、それらのCSSファイルを単に直接参照する方法も検討すべきです。application.html.erbファイル内の stylesheet_link_tagを以下ののように展開すれば、他のCSSファイルを参照できます。

<%= stylesheet_link_tag "application", "other", "styles", "data-turbo-track": "reload" %>

🔗 Q3: 既存プロジェクトのSassC::SyntaxError例外を回避するには?

一部のCSSパッケージでは、以前のバージョンのRailsで用いられていたデフォルトのSassC Rails統合でサポートされていない新しいCSS機能が使われていることがあります。このような非互換性に遭遇すると、assets:precompileを実行したときにSassC::SyntaxErrorのようなエラーが発生する可能性があります。

これを修正するには、bundle remove sass-rails(sassc-railsを使っている場合はbundle remove sassc-rails)を実行します。

🔗 Q4: production環境で application.css not in asset pipelineが発生しました

よくある原因は、ビルドコンポーネントで使われる出力ディレクトリがそのリポジトリに存在していないというものです。app/assets/buildsディレクトリを利用可能にしておく必要があります。このディレクトリ内に.gitkeepファイルを追加しておけば、production環境で利用できるようになります。

🔗 Q5: ActionView::Template::Error: Error: Function rgb is missing argument $greenエラーを回避する方法を教えてください

このエラーは、Gemfile.lockにレガシーなsassc-railsが含まれている場合に発生する可能性があります。これは、プロジェクトを段階的に移行する途中で必要となるか、プロジェクトで直接制御できない間接的な依存関係である可能性があります。
この場合は以下のように、このgemが既に実行しているバンドルにSprocketsがCSSを追加バンドルしないようにします。この対応は、production環境だけでなくすべての環境で行うようにしてください。そうしないとテストスイートが失敗する可能性があります。

# config/initializers/assets.rb
Rails.application.config.assets.css_compressor = nil

🔗 Q6: 更新されたCSSファイルがRailsで使われません

注意: ローカルでプリコンパイルしたファイルが存在すると、動的に生成されたファイルよりも優先して配信されます。解決するには、以下を実行してください。

rails assets:clobber 

🔗 node_modulesにあるサードパーティのスタイルシートを自分のバンドルに含める方法を教えてください。

以下のように@importステートメントで指定のスタイルシートへのパスを記述するときに、node_modules/とファイル拡張子を書かないようにします。

/* 使いたいファイルの場所: node_modules/select2/dist/css/select2.css */
@import "select2/dist/css/select2";

ライセンス

CSS Bundling for Rails is released under the MIT License.

関連記事

jsbundling-rails README(翻訳)

Rails 7: importmap-rails + tailwindcss-railsでnode.jsが不要な理由

Rails 7: dartsass-rails gemはNode.jsなしで使える


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。