Dart Sass(@use)の基本的な書き方と@importから乗り換える方法

Sassでファイルを呼び出す際に使っていた@importは廃止される予定でして、代わりに「@use」「@fowerd」を使うように推奨されています。自分も重い腰を上げて@useを使ってみました。

(※ Google日本語翻訳)

Dart SassとLibSassの両方がモジュールシステムのサポートを開始してから1年後、またはDart Sassがモジュールシステムのサポートを開始してから2年後のいずれか早い方(遅くとも2021年10月1日)に、@importグローバルコアライブラリ関数呼び出しと同様に非推奨になります。それはモジュールを通して作ることができます。

この非推奨が発効してから1年後( 遅くとも2022年10月1日)、@importほとんどのグローバル機能のサポートを完全に終了します。これには、すべての実装のメジャーバージョンリリースが含まれます。

https://sass-lang.com/blog/the-module-system-is-launched#future-plans

なぜ腰が重くなるかと言うと、@importを@useに書き換えるだけでは使えないからですね。@importでは定義した変数をそのまま使うことができたが、@useでは呼び出しもとのファイルを特定して変数を使用しなければならない、といった縛りが出てきます。

例えば以下のようなイメージです。

コピー@import "variable";

.hoge {
  color: $color-main;
}

↓ 呼び出し元のファイル名(もしくは名前空間)を利用する必要が出てくる

コピー@use "variable" as var;

.hoge {
  color: var.$color-main;
}

この記事では、Dart Sassでの基本的な書き方と、@importからの移行方法について紹介していきます。実際に手を動かさないと理解しづらい部分もあると思いますが、Sassを使っている方ならいつか対応する必要があることなので、時間を作って重い腰を上げましょう!

@useの使い方

@fowerdは基本的に呼び出すだけで使っているので説明は割愛します。@useについては、@importになかった特殊な使い方があるので実例を交えながら紹介していけたらと思います。

呼び出し先で変数を使う

冒頭でも紹介しましたが、一番の大きな変化は、呼び出し元ファイルを起点として変数やmixin、関数の使い方が変わるといった点ですね。

重複しますが、以前は呼び出し元ファイルの中で定義していた変数名を呼び出し先のファイルでもそのまま使えましたが、Dart Sassでは、呼び出し元を明示して使用する必要が出てきます。

コピー@import "variable";

.hoge {
  color: $color-main;
}

↓ @useの場合

コピー@use "variable" as var;

.hoge {
  color: var.$color-main;
}

上記Afterの「var.」に当たる部分は「名前空間」と呼ばれたりします。どこのファイルから呼ばれたものか定義するものと捉えていただて大丈夫です。

この名前空間にもルールがあって、以下の2点です。

  • asで繋ぐことで「名前空間」の名前を定義できる
  • asで繋いでいない場合は「名前空間」はファイル名となる

先ほどの例だと、as varとしているので、名前空間は「var」となり、呼び出す際も「var.$color-main;」としているわけです。

as varを削除し、@use "variable";だけにした場合の変数の呼び出し方は、ファイル名が名前空間となるので、「variable.$color-main;」となります。

@useでのファイル名

@useの右側に定義しているファイル名ですが、省略可能となるルールがあります。

これは@importでも馴染みがあるはずなので理解しやすいと思いますが、以下の3点ですね。

  • ファイル名の先頭の「_(アンダーバー)」は省略できる
  • 「.scss」の拡張子は省略できる
  • 「_index.scss」は省略できる

_heading.scssというファイルを@useする際は、以下のようになるわけです。

コピー@use "heading";

component/_index.scssというcomponentフォルダ内にある_index.scssファイルを読み込みたい場合は、以下のようになります。

コピー@use "component";

@importを@useに書き換える手順

これまでは、FLOCSSで以下のようなフォルダ構成で@importして使っていました。(ファイルは割愛します)

setting

function

foundation

layout

component

project

utility

style.scss

gulp-sass-glob」でまとめていたので以下のような書き方となっています。なお、@useではglobでまとめるこができないので、その恩恵が受けられくなりました。。

コピー@import "setting/**";
@import "function/**";
@import "foundation/**";
@import "layout/**";
@import "component/**";
@import "project/**";
@import "utility/**";

globでまとめることができない

もしgulpで「gulp-sass-glob」などを使って、まとめて出力している方がいたら、ちょっとだけ悲報かもしれません。

Dart Sassの@use、@fowerdの書き方では以下のような「gulp-sass-glob」を使ってまとめることはできなさそうです。

コピー@use "component/**";

ファイルが増えるたびに一つひとつを@useもしくは@fowerdして手動で管理していく必要がありそうです。

変数や関数の定義は一つにまとめる

@useでは呼び出し先で呼び出し元のファイルを定義する必要が出てきます。都度、settingとfunctionを呼び出すのが面倒なので、ここを1つにまとめます。(2つが1つになるだけですが…)

変数のまとめ方は主に以下の記事を参考にさせていただきました。

「global」というフォルダを用意し、ここに「setting」フォルダと「function」フォルダの中身を統合するような形で格納します。わたしはボリュームが少ないので、ファイル化しましたが、フォルダのまま入れてもいいと思います。

global

_index.scss

_variables.scss

_function.scss

foundation

layout

component

project

utility

style.scss

こうすることで、呼び出し先で以下のように定義することで、定義したすべての変数や関数を使うことができるようになります。

例えば、「component/_button.scss」で使う場合は、以下のようにglobalの変数郡を読み込んで変数を使うようなイメージです。

global/_index.scssにglobal内のファイルをまとめてあげて、

コピー@forward "variables";
@forward "function";
// その他global内のファイルすべて

各コンポーネント用のファイル内で呼び出して変数や関数を使うようなイメージです!

コピー// component/_button.scssで使っている例
@use "../global" as global;

.c-button {
  background-color: global.$color-main;
}

globalファイルはすべてのファイルで読み込む

@import的にsettingやfunctionで定義した変数を使いたい場合は、「foundation」「layout」「component」「project」「utility」フォルダ内のすべてのファイルの先頭で「global」の定義を読み込んでおく必要があります。

コピー@use "../global" as global;

// 読み込んだ後にCSSの記述

変数を書き換える

一番面倒なのは変数の書き換えですね。@useによって名前空間を先頭につけるというルールが新たにできました。

各ファイルで膨大に使われている変数を、(今回の名前空間の例だと)global.$var-nameといった形に書き換えていく必要があるわけですね。

コピー@use "../global" as global;

.c-button {
  background-color: global.$color-main; // 変数が使われているところは全部書き換える

  @include global.mq('sp') { // mixinや関数が使われているところも全部書き換える
    width: 100%;
  }
}

各フォルダ内のファイルを_index.scssでまとめる

一般的には当たり前にやっていることかもしれませんが、「gulp-sass-glob」で自動でまとめていた自分は、この作業をする必要がありました。
(しなくてもいいですが、呼び出しの大本となるstyle.scssの記述量が膨大になる恐れ…)

global

_index.scss

_variables.scss

_function.scss

foundation

_index.scss

layout

_index.scss

component

_index.scss

project

_index.scss

utility

_index.scss

style.scss

globalの例でいうと以下のようなまとめ方ですね。1つフォルダの対して1つの_index.scssを用意してフォルダ内で並列するファイルはすべてまとめるようなイメージです。

コピー// globalフォルダの_index.scssの例
@forward "variables";
@forward "function";
// その他global内のファイルすべて

globalで@forwardを使ったのは、その先にあるファイルの変数や関数を使いたいからで、変数を祖先のファイルまで使わせる予定がないであろうcomponentとかprojectとかは、@useでまとめていいと思います。

コピー// componentフォルダの_index.scss例
@use "button";
@use "heading";
// その他component内のファイルすべて

こうして作り直されたSassファイルを読み込むstyle.scssは以下のような記述になります。

コピー@use "foundation";
@use "layout";
@use "component";
@use "project";
@use "utility";

@import時代と大きな違いとしては、「setting」や「function」といった変数の定義に関するファイルもstyle.scssの先頭に書き込んで作っていたと思いますが、@useでは利用先となる各ファイルで呼び出さないと使えなくなったため、style.scssから変数を読み込むことはなくなりました。

@useと@fowerdの違い

ファイルの呼び出し方として、@useと@fowerdの2つがあります。この2つは、ちょっとややこしいですが、以下の違いがあります。

  • ファイル1では、ファイル1で@useしたファイル2で@useしているファイル3の変数は使うことができない。
  • ファイル1では、ファイル1で@useしたファイル2で@fowerdしているファイル3の変数は使うことができる。

今回のようにglobalで一括管理するような作り方の場合は、問題に遭遇することもないかもしれません。深い位置にある変数までアプローチしたい場合に@fowerdを検討すると覚えておくといいかもしれません。

Gulpファイルの書き換え

Dart Sassを使うにあたって、必要となるパッケージやgulpfile.jsの書き方が変わってきます。追加で必要となるパッケージは以下の2つですね。

コピーnpm install --save-dev sass fibers

gulpfile.jsの書き方は、以下のように変わります。(最小限だけで簡単に書いています)

コピー/* package */
const gulp = require("gulp");
const sass = require("gulp-sass");
const fiber = require('fibers');

/* select use compiler */
sass.compiler = require("sass"); // Dart Sass = "sass"

/* compile sass */
gulp.task("sass", function() {
  return gulp
    .src("./sass/**/*.scss")
    .pipe(sass({ // sass option
      fiber: fiber,
      outputStyle: "expanded"
    }))
    .pipe(gulp.dest("./css"));
});

sass.compiler = require("sass");によってDart Sassを使うことを明示しています。ちなみにnode-sassが従来のSassのようです。node-sassgulp-sassに内包されています。

Scss のコンパイラとして gulp-sass を利用していますが、現時点(2020/11/9)では gulp-sass はデフォルトだと node-sass を使用しています。

https://labor.ewigleere.net/2020/11/09/scss_transfer_libsass_dartsass/

fiberは処理の高速化に必要なパッケージのようです(あまり理解はしていない…)

コンポーネント毎の書き方が求められる?

@useの書き方から考えると、より限定的な書き方が求められているのかなと感じました。

  • どのファイルからの変数参照かの特定
  • 変数の利用範囲の限定

などの縛りが強くなり、どこに影響しているか分かりやすくなります。

今回は取り急ぎの@importからの移行ということで、変数や関数をglobalとしてまとめましたが、本来的には特定のコンポーネントに対する変数といった感じで分けるとよりよくなるかもしれません。

おわり

Dart Sassの基本的な使い方の紹介と、@importからの移行方法でした。

  • @importを@useにしただけでは使えないこと
  • @useで変数の利用範囲の制限がでてくること
  • @useでファイルの利用が限定的になること
  • gulp-sass-globが使えなくなること
  • Sass構造の見直しが必要になること

など、制限が加わることで書き方の見直し(設計方法も含めて)が必要になってくるかと思います。

いい機会なので、今のSassの構成がベストの方法かを見直す機会としてもいいかもしれませんね。いずれにしても従来の書き方から変えなければならない日はくるので、早いうちに慣れておきましょう!

この記事を書いた人

はにわまん

WordPressが得意なWeb屋。HPcode代表。

300件以上のWordPressカスタマイズを対応してきました。SE → 農家 → アフィリエイター → Web屋。生まれは三重県。