Sassの@import
ルールが将来的に廃止され、代わりに@use
や@forward
を使うことになるという。新しいルール@use
や@forward
は、Sass公式が推奨するDart Sassで既に採り入れられている。Node Sass (LibSass)が非推奨ということは、いずれRuby Sassのようにサポートされなくなることは十分に考えられる。

そんなわけで、当ブログのNuxt.jsプロジェクトでも使用中のNode SassをDart Sassに移行する方法を調べた。
はじめに:Node SassとDart Sassの違い
Node Sass
├── scss
│ ├── _base.scss
│ ├── _mixins.scss
│ ├── _variables.scss
│ └──style.scss
@import '_base';
@import '_mixins';
@import '_variables';
_variables.scss内の変数は、インポート先のstyle.scssだけでなく、_base.scssでも使うことができる。つまり、グローバル変数としてどのファイルからも参照可能である。
Dart Sass
Dart Sassの@use
は、_variables.scssの変数をインポート先でしか参照できない。
また、@use
で読み込まれたファイルたちはファイル名に応じた独自の名前空間を持つようになるため、読み込み先ではfilename.$variable
filename.mixin
といった指定が必要になる。
名前空間はas
で書き換えてコンパクトにすることもできる。@use
で読み込まれた変数・関数は、空間名+.
+変数・関数名という形式で使用する。
// variableをva、mixinをmxと命名した例
@use 'variables' as va;
@use 'mixins' as mx;
.element1 {
// variableの変数を使う
background-color: va.$hoge;
}
.element2 {
// mixinの関数を使う
@include mx.fuga;
}
@forward
は、ファイルをまたいで値を受け渡すことができる。変数や関数を1つのファイルにまとめたい時などに便利。但し、@forward
を使って読み込んだ値を変数・関数として使うことはできない。
実際の設計例
├── /scss/
│ ├── /global/
│ │ ├──_function.scss
│ │ ├──_index.scss
│ │ ├──_mixins.scss
│ │ └──_variables.scss
│ ├── /layout/
│ ├── /object/
│ │ ├── /component/
│ │ ├── /project/
└──style.scss
/global/ フォルダを作成。
function, mixinなど機能ごとにまとめたscssを@forward
で/global/_index.scssにインポートする。
@forward 'function'
@forward 'mixins'
@forward 'variables'
/global/_index.scssを@use
で読み込む。
/component/内ファイルで使う例
// 名前空間をgとする
@use '../../global' as g;
.element {
@include g.hoge;
}
各フォルダに_index.scssを作成し、同階層内に小分けにしたscssファイルがあれば@use
で読み込んで1つにまとめる。
@use 'header'
@use 'content'
@use 'footer'
style.scssで各フォルダの_index.scssを@use
でインポートし、最終的にまとめる。
@use 'global'
@use 'layout'
@use 'object/component'
@use 'object/project';
Nuxt.jsでの変更
パッケージのアンインストール&インストール
node-sassをアンインストールする。
npm uninstall node-sass
Dart Sass、ついでにfibers(処理高速化パッケージ)も入れておいた方がよいらしいのでインストールする。
※Node.js v16系はfibers非対応のため、インストールしない
npm install --save-dev sass
npm install --save-dev fibers
nuxt.config.jsの設定
Nuxt.jsのビルドにDart Sass(とfibers)を設定
export default {
build: {
loaders: {
scss: {
implementation: require('sass'),
// fibersをインストールした場合
sassOptions: {
fiber: require('fibers'),
},
},
},
},
}