LibSassからDartSassに変更〈@importから@useに移行したお話〉

フリーランスでWeb制作をしているすずのんです。先日久しぶりにVS Codeの拡張機能「Live Sass Compiler」でscssをコンパイルしようとしたのですが、gulpで使っていた@useの記述を入れていたようでコンパイルできないよ!って嫌われてしまいました。「Live Sass Compiler」は@useなど対応していないんですね。

じゃあもう今後はgulpでやっていこうかと思ったので、普段自分が使っているscssファイル構成を見直し@importから@useへ移行しました。Sassの公式で書かれているように、現在広く使われている@importが2022年10月頃には使用できなくなることは知っていましたが、移行するタイミングを逃しすぎていました笑 ということで今回は@importから@useへの移行について書いていきます。

使用している環境

エディタ:VS Code

コンパイラ:タスクランナーのgulpでコンパイル

今回のお話ではタスクランナーのgulpで、パッケージの「gulp-dart-sass」を使用して移行しています。

package.json

    "gulp-dart-sass": "^1.0.2",

gulpfile.js

//scss
const sass = require("gulp-dart-sass");
・
・
・

これ以外に出力するCSS形式を指定したりベンダープレフィックスを自動付与したりなど、既に色々設定してある状態で進めています。

やりたいこと

  • LibSassで使用している@importを公式推奨DartSassの@useにする
  • @useを使ったscssファイル構成の見直し

今までの状態

ファイル構成

 ┣ foundation
 ┃ ┣ _base.scss
 ┃ ┣ _mixin.scss
 ┃ ┣ _reset.scss
 ┃ ┗ _variable.scss
 ┣ layout
 ┃ ┣ _header.scss
 ┃ ┃ …
 ┃ ┗ …
 ┣ object
 ┃ ┣ component
 ┃ ┃ ┣ _button.scss
 ┃ ┃ ┃ …
 ┃ ┃ ┗ …
 ┃ ┣ project
 ┃ ┃ ┣ _company.scss
 ┃ ┃ ┃ …
 ┃ ┃ ┗ …
 ┃ ┗ utility
 ┃     ┣ _margin.scss
 ┃     ┃ …
 ┃     ┗ …
 ┗ style.scss

ファイルの一部は「…」で省略しています。

@importを使った書き方

style.scssで下記のように@importで変数もmixinも含めて全てのscssファイルを読み込んでいました。

//SASS (.scss)
//Foundation
@import "foundation/_reset.scss";
@import "foundation/_base.scss";
@import "foundation/_variable.scss";
@import "foundation/_mixin.scss";

//Layout
@import "layout/_header.scss";
・
・
・

//Object
@import "object/component/_button.scss";
・
・

@import "object/project/_company.scss";
・
・

@import "object/utility/_utility.scss";

ファイルの一部は「…」で省略しています。パーシャル(_reset.scssなどアンダーバーが付いた、コンパイル後に生成させないファイル)をインポートする場合は拡張子とアンダーバーを省略することもできます。

@importから@useに書き変えるだけではエラーになる

※以降ファイルの一部は「…」で省略しています。

例えば上記style.scssの@import@useに書き変えてみると、object/component/_button.scssからはfoundation/_variable.scssで設定した変数は参照できずエラーになりコンパイルできません。

style.scss

//SASS (.scss)
//Foundation
・
・
@use "foundation/variable";
・
・
// Object
@use "object/component/button";

foundation/_variable.scss

/***************************************
color
****************************************/
$colorBlack: #333333;

object/component/_button.scss

/***************************************
button
****************************************/
.c-textMore {
  padding: 40px 0 0;
  text-align: center;
  background-color: $colorBlack;
・
・
・
}

上記では「$colorBlackという変数がないですよ」とエラーが出ます。

@useはファイルごとに読み込む

@importではファイル名を読み込めばそのまま変数、関数、mixinを使用できましたが、@useはファイルごとに読み込む必要があるので、object/component/_button.scssfoundation/_variable.scssを読み込みます。

object/component/_button.scss

@use "../../foundation/variable";

/***************************************
button
****************************************/
.c-textMore {
  padding: 40px 0 0;
  text-align: center;
  background-color: $colorBlack;
・
・
・
}

けれども、また「$colorBlackという変数がないですよ」エラーが出ます。@useで読み込んだ場合には名前空間が発生するからです。

@useで読み込んだら名前空間を追記する

名前空間とはどこのファイルから呼ばれたものなのか定義するものです。名前空間は指定しなければ読み込み元のファイル名になります。読み込み元の変数を指定する際には、下記のように変数の前に読み込み元の名前空間の追記が必要です。

object/component/_button.scss

@use "../../foundation/variable";

/***************************************
button
****************************************/
.c-textMore {
  padding: 40px 0 0;
  text-align: center;
  background-color: variable.$colorBlack;
・
・
・
}

変数「$colorBlack」の前に「variable.」をドットで繋げました。これでコンパイルは成功です。

名前空間を指定するには下記のように「@use “../../foundation/variable” as v;」、「background-color: v.$colorBlack;」にします。「as hoge」で任意の名前に設定でき、名前空間の追記は「hoge.」と短い文字列にできます。

object/component/_button.scss

@use "../../foundation/variable" as v;

/***************************************
button
****************************************/
.c-textMore {
  padding: 40px 0 0;
  text-align: center;
  background-color: v.$colorBlack;
・
・
・
}

ファイル構成を見直す

@useの使い方はわかりましたが、ファイルごとに読み込む必要があるのでもう少しファイルをまとめて記述を減らします。

新・ファイル構成

 ┣ global
 ┃ ┣ _index.scss
 ┃ ┣ _variable.scss
 ┃ ┣ _mixin.scss
 ┣ foundation
 ┃ ┣ _index.scss
 ┃ ┣ _base.scss
 ┃ ┗ _reset.scss
 ┣ layout
 ┃ ┣ _index.scss
 ┃ ┣ _header.scss
 ┃ ┃ …
 ┃ ┗ …
 ┣ component
 ┃ ┣ _index.scss
 ┃ ┣ _button.scss
 ┃ ┃ …
 ┃ ┗ …
 ┣ project
 ┃ ┣ _index.scss
 ┃ ┣ _company.scss
 ┃ ┃ …
 ┃ ┗ …
 ┣ utility
 ┃ ┣ _index.scss
 ┃ ┣ _margin.scss
 ┃ ┃ …
 ┃ ┗ …
 ┗ style.scss
  • global」ディレクトリを作成して「_variable.scss」、「_mixin.scss」を「foundation」から移動。
  • global」に「_index.scss」を作成。「_index.scss」で変数(_variable.scss)とmixin(_mixin.scss)をまとめて読み込み、「global」の名前空間で参照するためです。
  • 他「foundation」、「layout」、「component」、「project」、「utility」にもひとつにまとめられるよう「_index.scss」を作成。
  • object」の階層を削除。FLOCSSを参考に構成していましたが階層が深いことでの良さが特になかったからです。

変数や関数をひとつにまとめる

globalに入っているファイルをまとめるために追加した_index.scssは下記のように記述しました。

_index.scss

@forward "variable";
@forward "mixin";

@useではなく@forwardが出てきましたが、例えば「component/_button.scss」などのファイルで、2つ以上前のファイルで定義された変数やmixinを使いたいからです。

@useを使うとそのファイルでしか使用できないので、「component/_button.scss」で変数を使いたい場合、

global/_variable.scss(変数の定義をまとめたファイル)

/***************************************
color
****************************************/
$colorBlack: #333333;
・
・
・

_index.scss(_variable.scss_mixin.scssを「global」の名前空間で参照するためにまとめたファイル)

@forward "variable";
@forward "mixin";

component/_button.scss(変数を使いたいファイル)

@use "../../global"as g;

/***************************************
button
****************************************/
.c-textMore {
  padding: 40px 0 0;
  text-align: center;
  background-color: g.$colorBlack;
・
・
・
}

こんな感じで2つ以上前のファイルで定義された変数を使いたい場合は「@forward」を使います。「component」など他のフォルダも同じようにまとめられますが、変数を2つ以上前のファイルまで使う予定がない場合は@useでまとめられると思います。

style.scssは下記のような記述になります。@useは各ファイルごとに読み込む必要があるので、style.scssでは変数やmixinは読み込みません

style.scss

//SASS (.scss)
//Foundation
@use "foundation";

//Layout
@use "layout";

//Component
@use "component";

//Project
@use "project";

//Utility
@use "utility";

まとめ

@importから@useへの移行、scssファイルの構成見直しは以上のような流れでした。名前空間つける個所を間違ったりmixinファイルに変数ファイルを読み込ませるのに手間取ったりしました笑

  • @importから@useに書き変えるだけでは使えない
  • @useはファイルごとに読み込む必要がある
  • @useを使うと名前空間が発生する
  • @use@forwardの違いを理解して使い分ける
  • scssファイルの構成見直す必要がある

DartSassへの移行やファイル構成の見直しをする良い機会でした!