No day younger than today

RubyとかRailsとか蒙古タンメンとか

【Rails】既存の CSS を cssbundling-rails でバンドルできるようにする手順

こんにちは、ふーが( @fugakkbn ) です。

先日、自作アプリを webpacker から jsbundling-rails に乗り換えました。

github.com

ならば CSS も cssbundling-rails に乗り換えたい!というのは自然な流れですよね。
というわけで乗り換えました。
jsbundling-rails と違ってハマるようなポイントはほぼなかったのですが、手順を書き残しておこうと思います。

github.com

前提

  • JS 周りのビルドは jsbundling-rails + webpack を使用しています。
    • bin/dev コマンドでローカルサーバが起動し JS のビルドも実行される前提です。
  • CSS フレームワークとして Bulma を使用しています。
    • 他のフレームワークでも、記事中に bulma となっている部分を置き換えてもらえれば OK なはず。

環境

Gemfile を更新する

bulma-rails という gem を使っていましたが、必要なくなるので削除します。
Bulma でない場合も、CSS フレームワークRails 使用するための gem は必要なくなると思うので削除して良いと思います。 その上で、 cssbundling-rails を bundle します。

# Gemfile
- gem 'bulma-rails'
+ gem 'cssbundling-rails'

install コマンドを実行する

bundle install が済んだら、以下のコマンドを実行します。
Bulma じゃない場合は必要なフレームワーク名を補ってください。

$ bin/rails css:install:bulma

実行すると、必要な yarn パッケージがインストールされたり、設定ファイルが更新されたりします。
ここで生じる差分を見てみます。

app/assets/stylesheets/application.bulma.scss

これがエントリーポイントとなる scss ファイルです。
ビルド時にはまずこのファイルが読まれることになります。

@charset 'utf-8';

@import 'bulma/bulma';

中身は、node_modules 配下の bulma/bulma を読み込んでいるだけですね。

app/assets/config/manifest.js

app/assets/config/manifest.jscss のエントリーポイントを読み込んでいる場合、その記述が削除されます。
CSS を引き続き Sprockets で管理する必要がある、という場合は注意が必要です。

//= link_directory ../stylesheets .css  ←これが削除される

Procfile.dev

Procfile.devbin/dev コマンドで実行されるファイルですが、こちらに CSS をビルドするコマンドが追加されます。

css: yarn build:css --watch

このコマンドは後ほど自分で package.json に定義する必要があります。

css build 用のコマンドを定義する

package.jsonCSS ビルド用のコマンドを追加します。

"scripts": {
   "build:css": "sass ./app/assets/stylesheets/application.bulma.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
 }

1つ目の PATH はエントリーポイントの PATH で、2つ目の PATH は出力先の PATH です。
これで、以下のコマンドで CSS のビルドを実行することができるようになりました。

$ yarn build:css

まぁ、bin/dev で立ち上げていれば変更を検知してビルドしてくれるので、自分でコマンド叩くことはないですけど。。。

既存の scss ファイルを読み込む

もともとの CSS 関連ファイルの構成は以下のようになっていました。
構成は千差万別だと思うのでここは参考までに。

app/assets
└── stylesheets
    ├── application.scss
    └── styles
        ├── _1-modules.scss
        ├── _button.scss
        ├── _common.scss
        ├── _fixed-footer.scss
        ├── _footer.scss
        ├── _form.scss
        ├── _header.scss
        ├── _index.scss
        ├── _material-icons.scss
        ├── _reset.scss
        ├── _searched_books.scss
        └── _welcome.scss

構成に差があれど、要はこれらを application.bulma.scss から読み込んであげれば良いです。

_1modules.scss は Bulma のうち必要な定義を読み込んでいるファイルなので削除します。
そして、 application.bulma.scss では glob 記法が使えないようで以下の書き方はできませんでした。

@import '../app/assets/stylesheets/styles/*';

仕方ないので1つずつ書きました。
これどうにかならないかな?scss 追加するたびにここにも追加しなきゃいけないので、忘れそう。。。

@import '../app/assets/stylesheets/styles/reset';

@import 'bulma/bulma';

@import '../app/assets/stylesheets/styles/button';
@import '../app/assets/stylesheets/styles/common';
@import '../app/assets/stylesheets/styles/fixed-footer';
@import '../app/assets/stylesheets/styles/footer';
@import '../app/assets/stylesheets/styles/form';
@import '../app/assets/stylesheets/styles/header';
@import '../app/assets/stylesheets/styles/index';
@import '../app/assets/stylesheets/styles/material-icons';
@import '../app/assets/stylesheets/styles/searched_books';
@import '../app/assets/stylesheets/styles/welcome';

ちなみに読み込みの起点は node_modules からになります。
@import ./styles/... のようには書けないので注意が必要。

bin/dev でローカルサーバを立ち上げる

ここまで来たらビルドできるようになっています。 bin/dev でサーバを立ち上げて、エラーなく以下の表示が出れば成功です。

Compiled app/assets/stylesheets/application.bulma.scss to app/assets/builds/application.css.

本番反映

本番でのビルド方法は assets:precompile を使えば OK です。 成功するとビルドされた csspublic/assets 配下に吐かれます。

おわりに

意外とすんなり乗り換えができました。
エントリーファイルで glob 記法が使えないのだけどうにかならないかなあ。
なにか良い書き方をご存じの方、ぜひ教えてください🙏