Help us understand the problem. What is going on with this article?

Railsで複数のSass(.scssファイル)を使用する際の読み込み方法

はじめに

RailsでSassを使用し、かつファイルを用途・適応範囲に応じて複数に分割したとき、どのような構成、読み込み方式にするかを実際の失敗談交えながら、記載したいと思います。
最初に「つまづいたこと」で、私が体験した発生した事象や原因などを書いていますが、必要なければ読み飛ばしてもらえればと思います。

環境

ruby: 2.6.4
rails: Rails 6.0.3.1 (sass-rails gemを使用)

まず結論

Railsで複数のSassを使用する際には、読み込みをSprocketsディレクティブ方式(require_tree)ではなく、@importで読み込むこと

つまづいたこと

携わったプロジェクトではSassを使用しており、かつスタイルファイルをメンテしやすくするため、コントローラ単位で.scssファイルを作成していた。
stylesheets直下のapplication.scssで全体に共通のスタイルを設定し、stylesheets/main配下に複数の.scssファイルを配置。

application.scssでは、以下の内容を記載していた。
1. ディレクティブ方式でmain配下のscssファイルを読み込み
2. その後bootstrapなどを読み込み(@import )
3. 最後に共通スタイルを設定。

application.scss
 中略 
 *= require_tree ./main 
 *= require_self     *= require_self
 */  

@import "bootstrap/scss/bootstrap";

 中略 
// 共通スタイル
body {  
  font-family: ....
}
 中略 

やろうとしたこと

今回、共通で使用する変数 (ex $main-color: #3D85C6;)を作成して、各.scssファイルで使い回そうと思い、以下のように共通変数の定義を追記した。

application.scss(改修後)
〜 中略 〜
 *= require_tree ./main 
 *= require_self     *= require_self
 */  

@import "bootstrap/scss/bootstrap";

〜 中略 〜

// 共通変数
$main-color: #3D85C6;   

// 共通スタイル
body {  
  font-family: ....
}
〜 中略 〜

ただ、この状態だとmain配下のscssファイルで変数を使用するとエラーになったため、変数の読み込みが必要だと思い、main配下のscssファイル側でapplication.scss@importした(今思えば、なぜこんな書き方をしたのか、後悔しかない・・・)
結果、main配下のscssファイルでも、変数を使用でき、スタイルも適用されてめでたしめでたしと思っていました。

その後、起こったこと

カスタマイズを進め、applicaiton.scssに変更を加えていく中で、不可解な現象が、、、

  • ブラウザの検証機能でスタイルを見ると、同じスタイルが2つある
  • application.scss内のとあるクラスのスタイルから、一部プロパティを削除しても反映されない (前述のとおり同一スタイルが2つ存在し、片方しかプロパティ削除が反映されていない)

スクリーンショット 2020-08-17 11.45.38.png

原因

すでにお気づきかもしれませんが、「やろうとしたこと」の中で、main配下のscssファイルで、application.scssをimportしてしまったたため、
そこに記載したスタイルが二重で読み込まれてしまいました。なおかつapplication.scssでimportしたbootstrap関連のscssも二重で読み込まれてました。
ただ、applicaiton.scss内のスタイルを変更しても、反映されない原因は結局わからず・・

というわけで、main配下のscssでのimportを削除するとともに、railsで複数のscssファイルを利用するためには、どのような読み込み方法良いのか調べることになりました。。

railsで複数のscssファイルを利用際の適切な読み込み方法

調査した結果

railsguide, rails-sass(gem)のページに記載の通り、railsで複数のSass(.scssファイル)を使用する際には、Sprocketsディレクティブで読み込まずにSass@importルールを使用する必要があります。

ディレクティブ方式だと、宣言した変数やmixinが他のscssファイルから利用できない。(まさしく今回私が体験した内容)

Sassファイルを複数使用しているのであれば、Sprocketsディレクティブで読み込まずにSass @importルールを使用する必要があります。このような場合にSprocketsディレクティブを使用してしまうと、Sassファイルが自分自身のスコープに置かれるため、その中で定義されている変数やミックスインが他のSassから利用できなくなってしまいます。

Important Note
Sprockets provides some directives that are placed inside of comments called require, require_tree, and require_self. DO NOT USE THEM IN YOUR SASS/SCSS FILES. They are very primitive and do not work well with Sass files. Instead, use Sass's native @import directive which sass-rails has customized to integrate with the conventions of your Rails projects.

最終的なapplicaiton.scssの記載内容

最終的には以下のような記述内容にしました。
これにより、common.scssで定義した変数が他のmain配下のscssファイルでも読み込むことができました。

  • applicaiton.scssから、reuire_tree, require_selfの記載を削除
  • 元々applicaiton.scssに記載していた共通スタイルと変数は、common.scssを新たに作成して移管
  • @importでcommon(共通スタイル)、main配下のスタイルを順に読み込み
application.scss(最終)
〜 中略 〜
 *      
 */

@import "bootstrap/scss/bootstrap";

@import "common";
@import "main/*";

参考文献

あるべきscssファイルの取り込み方法を理解するために大変参考になりました。

rails/sass-rails

アセットパイプライン - Railsガイド

great084
yanbaru-expert
エンジニア転職が成功するまで無期限に超手厚いサポートをする頭おかしい講座、やんばるエキスパートです。当講座ではプログラミングの教材学習だけでなく、毎週頻繁にプログラミングやマーケティングに関する勉強会を行ったり、開発チームを組んで開発の実践を行ったりしています。Qiitaでは、日々の学んだことを投稿していきます。
https://yanbaru-expert.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした