LoginSignup
0
0

More than 5 years have passed since last update.

@import のディレクトリ内にファイルがないと assets:precompile でコケる

Last updated at Posted at 2018-10-06

同じ轍を踏まないためにも、人柱になった自分を供養するためにも、ここにメモしておきたいと思います。
ちなみにアホかと思いますが、この件で4~5時間くらい悩んでいました。

前提

以下の条件でCSSをコンパイルしたい要件だったので、普通に何も考えずに assets:precompile するわけにはいきませんでした。

  • Railsでassets:precompileする対象のマニフェストファイルに、 require_self require_tree などのディレクティブは書かない
  • 必要なディレクトリ・ファイルはすべて @import して読み込む順番を制御する
  • assets/stylesheets/ 以下のCSSファイルをごっそり整理するために、ファイルを削除しまくったり、一時的に空のディレクトリを用意したりしておく必要がある

TL;DR

結論を先に書くと、 @import する対象のディレクトリ内に何もファイルを置いていない状態だと、エラーが起きてしまいます。なので、空のファイルであっても、便宜的に置いておく必要があったようです。ちなみに、 .keep ではだめでした。ちゃんと assets:precompile の対象となる拡張子 (.scss、.coffeeなど)じゃないとだめなようです。

assets/stylesheets/以下
mixins/
  └ _buttons.scss # 中身はまだ空っぽ
variables/
  └ _colors.scss # 中身はまだ空っぽ
templates/
  └ users/
      └ foo.scss # 中身はまだ空っぽ
      └ bar.scss # 中身はまだ空っぽ
application.scss
application.scss
@import "variables/*";
@import "mixins/*";
@import "templates/**/*";

なぜこういうディレクトリ構成にしたかったか

通常、Railsでアセットパイプラインを管理する場合、 assets/stylesheets/ 以下に、マニフェストファイルを置いておくと思います。デフォルトだと以下のようなディレクティブの書かれたファイルがおそらくあるでしょう。

application.css
/* ...
*= require_self
*= require_tree .
*/

ただこの場合だと、呼び出すファイルの順番をコントロールできないようです

2.4 マニフェストファイルとディレクティブ | Rails Guide アセットパイプライン

ディレクティブは記載した順に実行されますが、require_treeでインクルードされるファイルの読み込み順序は指定できません。従って、特定の読み込み順に依存しないようにする必要があります。

たとえば共通で使っている変数なんかもいちいち各ファイルで呼び出さないといけなかったりします。うーんこれはDRYじゃない。

foo.css
@import "../variables/*";

.foo {
  /* some styles */
}
bar.css
@import "../variables/*";

.foo {
  /* some styles */
}

そこで、マニフェストファイル内ですべて @import しちゃえ!と思って、requireなんとかをやめてみたというわけです。そしたら、冒頭のようなディレクトリ構成でも、各ファイルで @import する必要もなくなるでしょう。

はたして、この構成が効率良いのかはまだ検証の余地があると思いますが、コントロールできる範囲が明確になって良き…といった感じです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0