@import廃止なので@useと@forwardに切り替えた

代表取締役 YUSUKE HIRAMOTO
  • このエントリーをはてなブックマークに追加

SASSを利用している人なら誰でも使っているであろう「@import」が2022年に廃止となる予定です。
公式サイト
https://sass-lang.com/blog/the-module-system-is-launched

「このままでは今のファイル構造で上手く機能しなくなってしまう。」
と思ってから早1年以上。
重い腰をやっとあげた理由は2つあります。
1つ目は、2022年になったところで「もう流石に切り替えるしかないな」と思ったから、
2つ目は、社内の開発環境を整えて生産性とクオリティの向上を図るためです。

@useと@forwardについて

@useは@importと同じく「SASSファイルに、別のSASSファイルを読み込むこと」ができます。

コンパイルできない問題

まず最初にぶつかった壁が「コンパイルできない問題」でした。
SASSのコンパイルに「prepros」を使用しているのですがコンパイルできない。
コードがおかしいのかと思い試行錯誤したけどコンパイルできない、、、
小一時間悩んで解決できなかったので、後輩のエンジニアに「コンパイルできないんだけど。」とチャットを送ってみると、「休憩がてらみるのでファイル送ってください」と即レスきました、ありがたい。ファイルを送った直後に「コンパイルできましたよ」と、、、持つべきものは優秀なエンジニアの後輩ですね。
結局コンパイルできなかった原因は、「prepros」のバージョンが古かったからでした。
もし、コンパイルできなかったらツールのアップデートも試してみると良いかもしれません。

「コンパイルできない問題」を解決できたついでに、色々質問してみました。

HIRAMOTOチャット ここから ーーーーーーーーーーーーーー
私はそもそも名前空間をまだ理解してないんだよね、
情報読み漁ってるけど
ーーーーーーーーーーーーー ↑HIRAMOTOチャット ここまで

↓後輩エンジニア チャットここから ーーーーーーーーーーーー
要はグループ名ってことですよ。
青色ベースのデザインと赤色ベースのデザインとでそれぞれvariablesが用意されてるときに

@use "blue-theme" as theme
body {
 color: theme.$theme-color;
}

で青色ベースにしたうえで、

@use "red-theme" as theme

って書き換えれば、色が変えられるように、
「themeってグループ名で定義したものを使うよ」
って宣言しておけば、そのグループの中身までは呼び出し元は興味なくなる感じ。

参考サイトとかで良く謡われる名前空間のメリットは上記ではなくて、
「同じ変数名・関数名を複数定義できる」と謡ってて、
たとえばjavascriptで一般公開されてるライブラリを使おうと思ったときに、
もしそのライブラリがイマイチで、単純に関数を定義してるものだったら、
その関数名が自前の関数名と被って思ったような挙動をしてくれなくなります。

例)

カルーセルのライブラリ:setColor
自前の関数:setColor

$obj = $(this).find('.hoge');
setColor($obj)                                     ⇒ どっちのsetColorかわからなくてエラーになる。

こいつらをグループ化してあげることで共存が可能。

$obj = $(this).find('.hoge');
Carousel.setColor($obj)

たいていのライブラリはこういった独自の名前空間を用意してるので、関数名がかぶっても名前空間名がかぶってなければ問題ないって感じです。

これをCSSにも適用しよう、ってのが@useの目的かと。
ーーーーーーーーーーーーー ↑後輩エンジニア チャットここまで

ということでよくわかりませんが、実際に手を動かしながら理解しようということで早速@useを使ってみました。

@useの使い方

@useは、@importが廃止されて使用できなくなるので、その代わりとして推奨されています。具体的にどのように使い方が違うのかを調べながら実践してみました。

別のSASSファイルを読み込む

下記ファイル構成のフォルダがあるとします。

- sass
 ├ variables.scss
 └ index.scss

@importの場合、使い方は下記です。

@import '読み込むファイルのディレクトリ';

/* index.scss */@import 'variables';

これ↑を@useに置き換えると、

@use '読み込むファイルのディレクトリ' as 名前空間;

/* index.scss */@use 'variables' as var;
as+名前空間

asの後に名前空間と呼ばれる任意の文字列を記載します。名前空間はそのファイルの変数を使用するときに使います。

名前空間を記載しなくても使用できるという情報がありますが、私の環境だとコンパイルエラーがでました。

省略可能ルール
1、アンダーバーを省略できる

@import同様、ファイル名先頭のアンダーバー(_)を省略が可能です。
下記ファイル構成の場合、

- sass
 ├ _variables.scss
 └ _index.scss

下記で読み込めます

/* index.scss */
@use 'variables' as var;
2、拡張子「.scss」を省略できる

@import同様、拡張子「.scss」を省略することが可能。

/* index.scss */
@use 'variables.scss' as var;

ではなく、拡張子を省略して下記記述で使用することができます。

/* index.scss */
@use 'variables' as var;
3、index.scssを省略できる

index.scssを省略して読み込むことが可能。
下記ファイル構成の場合、

- style.scss
- sass
 ├ _variables.scss
 └ _index.scss

sassフォルダ内のindex.scssファイルを読み込む場合は下記コードで読み込むことが可能。

/* style.scss */
@use 'sass' var sass;

別ファイルの変数を使用する

別ファイルの変数を使用するときは、下記で使用することができます。

名前空間.$変数

var.$color

下記ファイル構成のフォルダがあるとします。

- sass
 ├ _variables.scss
 └ _index.scss

_variables.scssには下記変数が記載されているとします。

/* _variables.scss */$color1: #000000;$color2: #FFFFFF !default;

index.scssで_variable.scss内の変数を使用するには下記コードになります。

/* index.scss */@use 'variables' as var;
.example1 {
        color: var.$color1;
}.example2 {
        color: var.$color2;
}

先ずは、varibles.scssファイルを読み込みます。

@use 'variables' as var;

名前空間を「var」として定義。

varibles.scssファイルの変数$colorを使用するには下記のように記載。

.example1 {
        color: var.$color1;
}.example1 {
        color: 名前空間.変数;
}
withで変数を変更

​​下記ファイル構成でvariables.scssに変数が記載されている場合、

- sass
 ├ _variables.scss
 └ _index.scss/* _variables.scss */

$color1: #000000;
$color2: #FFFFFF !default;

index.scssで読み込むときwithを用いると変数を変更することが可能。

但し、変更前の変数が「!defaultフラグ」が使用されている場合にのみ変更可能です。

@use 'variables' as var with (
        $color2: #CCCCCC
);
.example2 {
        color: var.$color2; //コンパイルできる
}

複数の変数を変更する場合は、「,」で区切ります。

@use 'variables' as var with (
        $example1: #CCCCCC,
        $example2: #CCCCCC
);

@forwordの使い方

@useは読み込んだファイル以外では変数を使用できません。
例えば下記ファイル構成の場合、

-style.scss
-sass
├ _variables.scss ├ _utility.scss
└ _index.scss

sass/variables.scssに変数が記載されているとします。

/* sass/variables.scss */
$color: #000000;

sass/index.scssでvariablesを読み込みます。

/* sass/index.scss */
@use 'variables' as var;

style.scssでsass/index.scssを読み込みます。

/* style.scss */
@use 'sass' as sass; //_indexの読み込みは省略可
.foo {
        color: sass.$color; //コンパイルエラー
        color: sass.var.$color; //コンパイルエラー
}

そこで登場するのが@forword。
@forwordはハブになるファイルに使用します。

例えば下記ファイル構造の場合、

-style.scss
-sass
├ _variables.scss
├ _utility.scss
└ _index.scss

variablesに下記変数が記載されているとします。

/* sass/variables.scss */
$color: #000000

sass/_index.scssに@forwordで同じ階層の全ファイルを読み込みます。

/* sass/index.scss */
@forward 'variables';
@forward 'utility';

style.scssで変数が使用可能になります。

/* style.scss */
@use 'sass' as sass; //_indexの読み込みは省略可
.foo {
        color: sass.$color;
}

@useによるメリット

変数を使用するのに名前空間を記載しなければならないので、同じ変数による上書きや衝突を防ぐことができるのがメリットです。

@useによるデメリット

@importで変数などを読み込めば、それ以下で読み込むファイルでも自由に変数やミックスインを使用できました。
しかしながら、変数やミックスインが記載されているファイルを読み込まなければ使用できません。
さらには名前空間を変数の前につけなければエラーが出てしまうのがデメリットであると言えます。
名前空間を変数の前につけなければならないのは慣れでなんとかなると思いますが、
変数やミックスインを読み込むファイルが増えるとなるとファイル構成自体を検討する必要があります。

SASSファイル構成

@importから@useに切り替えることで変更することになるであろうポイントは、SASSファイル構成であると考えられます。
_index.scssにまとめて利用すると良いかもしれません。

例えば下記ファイル構成であれば、

-style.scss
- sass
 ├ base
 │ ├ _.scss
 │ ├ _.scss
 │ └ _index.scss
 ├ layout
 │ ├ _.scss
 │ ├ _.scss
 │ └ _index.scss
 ├ component
 │ ├ _.scss
 │ ├ _.scss
 │ └ _index.scss
 ├ project
 │ ├ _.scss
 │ ├ _.scss
 │ └ _index.scss
 └ plugin
 │ ├ _.scss
 │ ├ _.scss
 │ └ _index.scss

各フォルダ内の_index.scssに同階層の全ファイルを@forwardで読み込む。

/* 各フォルダ内の_index.scss */
@forward 'example1';
@forward 'example2';
@forward 'example3';

そしてstyle.scssファイルに@useで全フォルダを読み込めば1つにまとめることができます。

/* style.scss */
@use 'base';
@use 'layout';
@use 'component';
@use 'project';
@use 'plugin';

このような@use、@forwardの特性を活かしてファイル構成を検討した方が良いのではないでしょうか?

さいごに

他にも名前空間にアスタリスク(*)を設定することで変数使用時に名前空間の記述を不要にしたり、変数を別ファイルで上書きしたりなど、この記事では紹介していない機能もあるので公式HPは確認することをおすすめします。
公式HP:https://sass-lang.com/documentation/at-rules/use

  • このエントリーをはてなブックマークに追加

書いた人

代表取締役 YUSUKE HIRAMOTO

Ludius,inc.代表取締役。 執筆:小川雅人編著「中小企業の経営と診断」-持続ある社会活動の経営支援に向けて-「11章 中小企業の情報戦略」。

follow me