かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Sass の npm パッケージは sass と node-sass どっちを使えばいいの?

フロントエンド開発をしていて Sass の導入に sass になっているものと node-sass になっているものがあってどっち?ってなったのでメモ

node-sass は非推奨になっていた

Warning: LibSass and Node Sass are deprecated.
While they will continue to receive maintenance releases indefinitely, there are no plans to add additional features or compatibility with any new CSS or Sass features. Projects that still use it should move onto Dart Sass.
cf. node-sass - npm

node-sass (LibSass) が非推奨になった経緯

  • C++ で書かれた LibSass
  • LibSass を最新の CSS, SASS の状態に保つための開発リソース確保がが難しい状態が続いている
  • 例えば Sassモジュールシステムをサポートしていないなど最新のCSSおよびSass構文との互換性が徐々に失われていっている
  • 別に開発されている DartSass を使って欲しい

cf. Sass: LibSass is Deprecated

ということっぽい。

結論 sass (DartSass) を使おう!

DartSass である sass パッケージを使おう

node-sass (LibSass) から sass (DartSass) に乗り換える際の大きな変更点

DartSass では別ファイルの読み込みが Sass Module System の @import から @use に変更になっている。(@import は 2022年10月1日に廃止予定 cf. Sass: The Module System is Launched )

@use でのインポートはスコープと namespace を持つ

  • @use only executes a stylesheet and includes its CSS once, no matter how many times that stylesheet is used.
  • @use only makes names available in the current stylesheet, as opposed to globally.
  • Members whose names begin with - or _ are private to the current stylesheet with @use.
  • If a stylesheet includes @extend, that extension is only applied to stylesheets it imports, not stylesheets that import it.

cf. Sass: The Module System is Launched

@use で読み込まれた Sass ファイルは読み込まれたファイル内でのみ有効になり、as キーワードでネームスペースを設定できる

ファイルインポート時の namespace

@use "bootstrap" as b;

.element {
  @include b.float-left;
}

as * とすると namespace 名なし (top-level) で使用できる。
ただし、複数のモジュールを as * で読み込もうとするとエラーになる

@use "bootstrap" as *;

.element {
  @include float-left;
}

namespace を指定しない場合、モジュール名が namespace 名になる

@use "bootstrap";

.element {
  @include bootstrap.float-left;
}

多重読み込み

変数や mixin, function をまとめて読み込んだファイルを別で読み込みたいような場合、@use で読み込むと読み込まれたファイル内でしか変数や mixin が有効になりません。
多重読み込みで使用したい場合は @forward キーワードで読み込ませると多重読み込みしたファイルでも変数や mixin を使用することができるようになります。

🙅 @use だと多重読み込みされたファイルの内容にアクセスできない

// _variables.scss
$primary-color: #000;

// _mixins.scss
@mixin box() {
  padding: 1.2rem;
  background: #F4F4F4;
  border: 1px solid #666;
}

// _settings.scss
@use "variables";
@use "mixins";

// style.scss
@use "settings" as s;

.box {
  color: s.primary-color; // => NG
  @include s.box(); // => NG
}

🙆 多重読み込みをさせて使うファイルは @forward で読み込ませる

// 更に読み込ませることで使うファイルが `@forward` で読み込ませる
// _settings.scss
@forward "variables";
@forward "mixins";

// style.scss
@use "settings" as s; // settings は `style.scss` 内でのみ利用できる

.box {
  color: s.primary-color; // => OK
  @include s.box(); // => OK
}

!default キーワードのある変数の変更

!default キーワードの付いた変数宣言は同じ変数名があれば値を上書きしない定義されないです。
ライブラリ内で !default キーワードの使われた変数の値を変更するには、今までは先に同じ変数名を定義したファイルを読み込ませる方法が取られてきました。
Sass Module System では with キーワードを使って !default を持つ変数を変更することが出来るようです

// bootstrap.scss
$paragraph-margin-bottom: 1rem !default;
p {
  margin-top: 0;
  margin-bottom: $paragraph-margin-bottom;
}
@use "bootstrap" with (
  $paragraph-margin-bottom: 1.2rem
);

=> p の margin-bottom は 1.2rem になる


[参考]

過集中の回避と集中した時間を取るためにタイマー導入したらいい感じになりました!