【Sass】@importの廃止に伴い@useと@forwardに書き換える
はじめに
新しいもモジュールシステム導入で@use
, @forward
が追加され@import
が2022年10月1日に廃止予定です。それに伴い行った置き換え作業を残しておきたいと思います。
廃止に至った理由
さまざまな障害が発生しており、それらを解決するべく新しいモジュールシステム導入に至った。
- It was next to impossible to figure out where a given variable, mixin, or function (collectively called “members”) was originally defined, since anything defined in one stylesheet was available to all stylesheets that were imported after it.
- Even if you chose to explicitly import every stylesheet that defined members you used, you’d end up with duplicate CSS and strange side-effects, because stylesheets were reloaded from scratch every time they were imported.
- It wasn’t safe to use terse and simple names because there was always a possibility that some other stylesheet elsewhere in your application would use the same name and mess up your logic. To be safe users had to manually add long, awkward namespaces to everything they defined.
- Library authors had no way to ensure that their private helpers wouldn’t be accessed by downstream users, causing confusion and backwards-compatibility headaches.
- The @extend rule could affect any selector anywhere in the stylesheet, not just those that its author explicitly chose to extend.
Sassについて
SassにはDartSass、LibSass、RubySassと3種類存在するがLibSass、RubySassはすでに非推奨となっておりSass公式でDartSassを推奨している。@use
も@forward
も現在、DartSassだけがサポートしている。
@importを@useと@forwardに置き換える
実際に発生する置き換えパターンを4つ例にまとめてみる。(@import,@use,@forwardの詳細はドキュメントをご覧ください。)
パターン1: @importでscssファイルを読み込みスタイルをそのまま利用している
呼び出したスタイルをそのまま利用している場合は@import
を@use
へ変更するだけでOK。
body {
margin: 0;
}
- @import 'base';
+ @use 'base';
パターン2: @importで変数を読み込み利用している
@import
では呼び出した変数がグローバルとなりそのまま呼び出せるのに対し、@use
を利用する場合は呼び出し元を指定する必要がある。@use
ではデフォルトでファイル名に応じた名前空間を持つためvariables.$変数名
のように書く。
$color-text: #333;
- @import 'variables';
+ @use 'variables';
body {
- color: $color-text;
+ color: variables.$color-text;
}
補足
as
を使うと独自に名前空間を定義することができる
@use 'variables' as var;
body {
color: var.$color-text;
}
パターン3: @importでmixinを読み込み利用している
パターン2同様に@use
を利用する場合は呼び出し元を指定する。
$bg-color: #efebef;
@mixin bg() {
background-color: $bg-color;
}
- @import 'mixin';
+ @use 'mixin';
body {
- @include bg();
+ @include mixin.bg();
}
パターン4: 複数scssファイルを一つのファイルに集約して読み込み利用している
@use
では呼び出したファイル内の要素のみ利用できる。そのため複数ファイルを集約したファイルを呼び出しても複数ファイル内の要素は参照できない。そのため@forward
で@use
からの参照可能とする必要がある。
$color-text: #333;
$bg-color: #efebef;
@mixin bg() {
background-color: $bg-color;
}
- @import 'variables'
+ @forward 'variables'
- @import 'mixin'
+ @forward 'mixin'
- @import 'utils'
+ @use 'utils'
body {
color: utils.$color-text;
@include utils.bg();
}
実際に発生したエラー
Private members can't be accessed from outside their modules.
@use
してくるscssファイルの中で変数名に-
または_
をつけているprivate変数は呼び出すことができない。private変数を呼び出そうとするとエラーとなる。
SassError: Private members can't be accessed from outside their modules.
╷
116 │ color: variables.$--color-text;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
// NG
$--color-text: #333
// OK
$color-text: #333
Private members can't be accessed from outside their modules.
@use
は他のルールよりも先に書かなくてはいけない。書き換えの過程で@import
も存在している場合等、@use
よりも前に@import
がある状態だとエラーとなる。
SassError: @use rules must be written before any other rules.
╷
75 │ @use 'mixin';
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
// NG
@import 'variables'
@use 'mixin'
// OK
@use 'mixin'
@import 'variables'
さいごに
ドキュメントを読んでみてからと思っていたけど、コード例も多く載っているので実際に手を動かしながらの方が理解しやすかった印象です!
Discussion