Bulmaを使うためにRailsのフロント周りについて改めて調べてみた

個人開発で出くわした悩み事について書きます。
フロントエンドにあまりに疎いため、Bulmaを使おうとしたとき、Yarnで追加するのかbulma-rails gemを使うのか迷いました。
それぞれどういう違いがあるのか、改めて調べてみることにしました。

# bulma-railsは何をしているのか？

[bluma-railsというgem](https://github.com/joshuajansen/bulma-rails)があります。
READMEにはこう書かれています

    Integrates Bulma with the rails asset pipeline.

なるほど。asset pipelineを使うらしい。
asset pipelineという言葉に引っかかりを感じつつも、とりあえずgemの中身を見てみます。

## gemspecを見る

[こちら](https://github.com/joshuajansen/bulma-rails/blob/master/bulma-rails.gemspec)がbluma-railsのgemspecです。
[SassC](https://github.com/joshuajansen/bulma-rails/blob/master/bulma-rails.gemspec#L16)というgemに依存していることがわかります。
SassCは、[ffi](https://github.com/ffi/ffi)という他言語の関数を呼んだりできるgemを使って、
C++で書かれた[libsass](https://github.com/sass/libsass)を使ってSassを扱っています。

ffiというgem、初めて知りましたが面白そうなgemですね。

## コードを見てみる

app/assets/stylesheetsというディレクトリの下にbulma.sassというファイルがあり、ここでapp/assets/stylesheets/sassをimportしているのがわかります。

```
@charset "utf-8"
/*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */
@import "sass/utilities/_all"
@import "sass/base/_all"
@import "sass/elements/_all"
@import "sass/form/_all"
@import "sass/components/_all"
@import "sass/grid/_all"
@import "sass/layout/_all"
```

あれ、これはつまり[これ](https://github.com/jgthms/bulma/blob/master/bulma.sass)をapp/assets/stylesheets/bulma.sassに、app/assets/stylesheets/sassに[これ](https://github.com/jgthms/bulma/tree/master/sass)を置いた、って感じですね。

続いて、libのbulma-rails.rbを見てみます。
こんな感じ。

```
module Bulma
  class Engine < ::Rails::Engine
  end
end
```

Railsエンジンが出てきました。

エンジンも詳しくないので[RailsガイドのRailsエンジン入門](https://railsguides.jp/engines.html)を読んでみます。


> エンジンの中にあるアセットは、通常のアプリケーションで使われるアセットとまったく同じように振る舞います。
エンジンのクラスはRails::Engineを継承しているので、アプリケーションはエンジンのapp/assetsディレクトリとlib/assetsディレクトリを探索対象として認識します。

bulma-railsは、Railsが探索してくれるところにBulma使うのに必要なファイルを置いてくれるgemだということがわかりました。
置いたらあとはasset pipelineがよしなにやってくれるのでしょうね。

## asset pipeline

asset pipeline、随分ご無沙汰しており、どんな人なのか記憶にないので、改めて[Railsガイド](https://railsguides.jp/asset_pipeline.html)を読んでみます。

> アセットパイプラインはsprockets-rails gemによって実装され、デフォルトで有効になっています。

なるほど[sprockets](https://github.com/rails/sprockets-rails)がアセットのコンパイル、圧縮を頑張る仕組みなのですね。

> アセットパイプライン導入後は、app/assetsディレクトリがアセットの置き場所として推奨されています。このディレクトリに置かれたファイルはSprocketsミドルウェアによってサポートされます。

bulma-railsはapp/assets/stylesheets以下にscssファイルを置いてたので、sprocketsがサポートしてくれるというわけですね。

しかしファイル置くだけのgemって変だよな、と、調べていたところ以下の記事を見つけました。

[新しいRailsフロントエンド開発（1）Asset PipelineからWebpackへ（翻訳）](https://techracho.bpsinc.jp/hachi8833/2017_12_26/49931)


> 依存関係についてはどうでしょうか。Asset Pipelineを常に最新に保つのは大仕事です。プロジェクトにJavaScriptライブラリを1つ追加する場合、CDNから読み込んだコードをコピペしてapp/assetsやlib/assetsやvendor/assetsに置くか、誰かがgem化してくれるまでぼんやり待つ方法があります。その間にも、JavaScriptコミュニティは同じことをnpm installコマンド、今ならyarn addコマンド一発で管理しています。アップデートも同様です。YarnはJavaScriptをBundlerのように便利に扱うことができます。


な、なるほど、、、それでgem化して固めてたのか。先人の苦悩が伝わってきました。Yarnありがとう。

# webpacker + YarnでBulmaを追加するとどうなるのか？

Rails6ではwebpackerがデフォルトになっているので、webpacker + Yarnを使って同じことをやってみます。
ロゴが猫なのでYarnは好きです。

コードがあるほうがよいかなと[リポジトリ作りました。](https://github.com/itume/advent_calendar_2019_assets)さて、雑にrails newしてみますと[こんな出力が得られました](https://github.com/itume/advent_calendar_2019_assets/issues/1)。もりもりいろんなものがinstallされていることがわかります。

meowという気になる名前のモジュールがinstallされてますね。なんでしょうか。

    ├─ meow@3.7.0

[CLI app helperと書いてありました。](https://www.npmjs.com/package/meow)
meowなページで癒やされたので続きをやっていきます。

## 雑にアプリを作る

Yay! You’re on Rails!　の画面が出ましたが、Bulmaの使い所がないので画面を増やすために雑にscaffoldしていきます。

    rails generate scaffold cat name:string description:text

migrationしてrails sしてlocalhost:3000/catsを確認するとこんな画面が出ます。
<img width="855" alt="スクリーンショット 2019-11-24 10.16.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56357/cfdea095-6a43-9b6a-3c58-7353dc82abdc.png">
殺風景ですね。Bulmaを導入していきます。

## Bulmaを使っていく

    yarn add bulma

してみると、[こんな出力](https://github.com/itume/advent_calendar_2019_assets/issues/2)が出ます。
warningが出てますが、webpackerのissueで対策検討されているようなので今回はさらっと流していきます。

yarn add bulmaしてみると、[package.json、yarn.lockが更新され](https://github.com/itume/advent_calendar_2019_assets/commit/fcce37e26048927e23ca510e991b976a3bcd9a49)、node_modules以下にbulmaがinstallされます。node_modules以下は.gitignoreに書いてあるのでcommitに乗りません。これでBulmaが追加できました。

あとはRailsで使えるようにしていくだけ、なのですが、フロントエンド音痴ゆえここで大変苦戦しました。[Rails6でwebpackを使ってbootstrapを導入する記事](https://medium.com/@guilhermepejon/how-to-install-bootstrap-4-3-in-a-rails-6-app-using-webpack-9eae7a6e2832)を見つけたので、これを参考にやっていきます。

* application.sassを app/javascript/stylesheetsに作って、Bulmaのcssをimport
* app/javascript/packs/application.jsで上記をimport
* app/views/layouts/application.html.erb の stylesheet_link_tag を stylesheet_pack_tag に
* app/views/cats/index.html.erbの適当な要素にclassを追加

<img width="354" alt="スクリーンショット 2019-11-24 21.37.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56357/16c7a8ca-7385-dbec-000f-ac3d90d5c228.png">
これでBulmaのスタイルを適用できました。Bulmaが効いていることをチャッと確かめたかったので、New Catのリンクとh1にだけclassを振っております。

# まとめ

フロント開発から随分遠ざかっていたのでwebpackerについて調べる良い機会を得られました。しかしチャッとBulma使っていこう、というくらいのつもりだったのにwarningを追いかけてwebpackerのissueまで読むことになるとは思いませんでした。

asset pipelineを使っているbulma-railsは大変簡単に導入できたので、これはこれで良いなと思いました。ただ、長く開発していくアプリで使うならYarnで管理するのが良さそうですね。次はwebpackerではなく素のwebpackに挑戦してみようと思います。
この記事ではwebpackerの説明は省いてしまいました。webpackがどんなものなのかについては、24日に投稿する記事で紹介される予定です。お楽しみに。


明日は、@mochikichi321さんの「投稿画像の彩度低下問題を解決した話」です。明日もよろしくおねがいします！