読者です 読者をやめる 読者になる 読者になる

【Rails】【Bower】Staging(Production)環境でAsset PipelineでFont,Imageパスが取得できず404なってしまう場合

はじめに

AdminLTEはGemとしてもあったのですが、勉強も兼ねてbower-railsを使って
個人プロジェクトでbower-railsを使いつつ、AdminLTEを使って
管理画面を作成した際にハマったことをメモします。

なお、bower-railsとAdminLTEの初期インストールなどは割愛します。
HTMLテンプレートはSlimを使用しています。

結論

bowerのAdminLTEのものを使わず、FontやImageのパスを
Railsの機能で置き換え済みのGemを使用して解決した。

なお、Bootstrapのglyphiconは解決できなかったため
アイコン系は、font-awesomeに置き換えた

環境

Capistranoを使い、Vagrantに対してデプロイする設定をしています。

原因

Bowerで取得したライブラリのFontパスとImageパスが相対パスとなっていて プリコンパイルされた際にapplication.css, application.jsにすべて集約されてしまうため
パスがおかしくなってしまう。

詳細

以下の様な状態でbowerで設定していた。

f:id:fujikawa-y:20160421093602p:plain

「application.css.scss」は以下の通り

/*
 *= require admin-lte/bootstrap/css/bootstrap
 *= require admin-lte/dist/css/AdminLTE
 *= require admin-lte/dist/css/skins/skin-blue
 *= require admin-lte/plugins/iCheck/minimal/blue.css
 *= require fontawesome/css/font-awesome
 */

「application.js」は以下の通り

//= require jquery
//= require jquery-ujs
//= require admin-lte/bootstrap/js/bootstrap
//= require admin-lte/dist/js/app.js
//= require admin-lte/plugins/iCheck/icheck.min.js

上記の状態でデプロイをすると以下の様なエラーが発生してしまう。
f:id:fujikawa-y:20160424072533p:plain f:id:fujikawa-y:20160424072546p:plain

理由

Bowerでライブラリをインストールした場合、application.css, application.jsに
まとめられてしまいAsset Pipelineの考慮がされていないため。

調査

実際にbower_componentsのAdminLTEを参照すると以下のように記述してある。 例1:/bower_components/admin-lte/bootstrap/css/bootstrap.css(抜粋)

@font-face {
  font-family: 'Glyphicons Halflings';

  src: url('../fonts/glyphicons-halflings-regular.eot');
  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
  position: relative;
  top: 1px;
  display: inline-block;
  font-family: 'Glyphicons Halflings';
  font-style: normal;
  font-weight: normal;
  line-height: 1;

  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

例2:/bower_components/fontawesome/css/font-awesome.css(抜粋)

@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.6.1');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.1') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.6.1') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.6.1') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.6.1') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.6.1#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

問題なのは以下の箇所

url('xxx');

Qiitaに記事が書かれている。 qiita.com

qiita.com

また、公式ドキュメントも確認する。 railsguides.jp

解決方法

Railsのためにパスを置き換え済みのGemを使用する。

Gemfile

gem 'icheck-rails'
gem 'font-awesome-sass'

bundle installを行い、css, jsは以下の通りに記述する。

application.css

@import "icheck/minimal/blue";
@import "font-awesome-sprockets";
@import "font-awesome";

application.js

//= require icheck

まとめ

RailsJavascript, css周りはAsset Pipelineで意図しない動きになってしまうことが
よくわかった今回の内容でした。ローカル環境で動いたと喜んでいないで
サーバにデプロイして、ちゃんと動く、表示されたら喜ぶようにしようと思いました。