39
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

un-T factory! XAAdvent Calendar 2021

Day 12

Dart Sassへの移行でつまづいたこととか

Last updated at Posted at 2021-12-11

公式ブログによると新しいモジュールシステム導入に伴い、これまで使用されていた@importルールは2021年10月には非推奨に、2022年10月にはサポートが終了する予定になっています。
これにより新しいモジュールシステムをサポートしていないLibSassは非推奨になり、Dart Sassへの移行が推奨されるようになりました。
今回はDart Sassへの移行の際につまづいたことや気づいたことをまとめたいと思います。

除算演算子(/)はsass:mathモジュールに変更する

除算演算子をそのままコンパイルすると警告が出力されます。

.hoge {
  width: (100% / 3); // Deprecation Warning: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
}

CSSではスラッシュを演算子ではなくセパレータ(区切り文字)として使用するものが増えてきており、これに倣ってSassもスラッシュをセパレータとして再定義することになったようです。
そのため演算子として記述していたスラッシュは非推奨となり、sass:mathモジュールのdiv関数に変更する必要があります。
ただしcalc()関数の内部にあるスラッシュは非推奨の対象となりません。

変更後

@use "sass:math";

.hoge {
  width: math.div(100%, 3);
}

map-get関数はsass:mapモジュールに変更する

Dart Sassではすべての組み込み関数が組み込みモジュールに移行されました。
それぞれ名前も変更され、map-getmap.getの形式で呼び出す必要があります。

$breakpoints: (
  sm: 768px,
  md: 960px,
  lg: 1200px,
);

@mixin max-screen($breakpoint) {
  @media (max-width: #{map-get($breakpoints, $breakpoint)}) {
    @content;
  }
}

.hoge {
  margin-top: 80px;
  @include max-screen(sm) {
    margin-top: 160px;
  }
}

変更後

@use "sass:map";

$breakpoints: (...);

@mixin max-screen($breakpoint) {
  @media (max-width: #{map.get($breakpoints, $breakpoint)}) {
    @content;
  }
}

.hoge {...}

また、Dart Sassでは2つ以上の引数でのmap.getの呼び出しをサポートしています。
第二引数、第三引数と記述していくことで、ネストされた値を取得できます。

$easing: (
  "ease-in": (
    "easeInQuad": cubic-bezier(0.550, 0.085, 0.680, 0.530),
    "easeInCubic": cubic-bezier(0.550, 0.055, 0.675, 0.190)
  )
);

@debug map.get($easing, ease-in, easeInCubic); // cubic-bezier(0.55, 0.055, 0.675, 0.19)

@forward@useを併記して読み込みを簡潔にする

以下のようなファイル構成があるとします。

_variables.scss
$color-main: #f88 ;

$breakpoints: (
  sm: 768px,
  md: 960px,
  lg: 1200px,
);
_mixin.scss
@use "sass:map";
@use 'variables' as *;

@mixin max-screen($breakpoint) {
  @media (max-width: #{map.get($breakpoints, $breakpoint)}) {
    @content;
  }
}
style.scss
@use 'variables' as *;
@use 'mixin' as *;

.un_heading {
  color: $color-main;
  font-weight: 700;
  @include max-screen(sm) {
    font-weight: 400;
  }
}

_variables.scssに定義されている変数を利用する場合、記述したいファイルの先頭で_variables.scssを読み込む必要があります。
ただし今回の場合_mixin.scss@forwardの記述を追加することで、_mixin.scssを読み込んでいるstyle.scssで変数の使用が可能になります。
注意点として@forward@useより前に記述しなければなりません。

変更後

_mixin.scss
@use "sass:map";
@forward 'variables';
@use 'variables' as *;

@mixin max-screen($breakpoint) {...}
style.scss
@use 'mixin' as *;

.un_heading {
  color: $color-main;
  font-weight: 700;
  @include max-screen(sm) {
    font-weight: 400;
  }
}

Globを使う

これまではgulp-sass-globというプラグインで対応していましたが、このプラグインは@useルールに対応していないのでGlobが使えません。

├ src
│ └ scss
│   ├ _partials
│   │ ├ _function.scss
│   │ ├ _mixin.scss
│   │ └ _variables.scss
│   └ style.scss
└ dest
  └ css
    └ style.css
gulpgile.js
const gulp = require('gulp');
const sass = require('gulp-dart-sass');
const sassGlob = require('gulp-sass-glob');

const styles = () => {
  return gulp.src('src/scss/**/*.scss')
    .pipe(sassGlob())
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('dest/css'));
};
style.scss
@use '_partials/*' as *; // Error: Can't find stylesheet to import.

対象法としてgulp-sass-globの代わりにgulp-sass-glob-use-forwardを使うことで、Globが利用できます。

変更後

gulpgile.js
const gulp = require('gulp');
const sass = require('gulp-dart-sass');
const sassGlob = require('gulp-sass-glob-use-forward');

const styles = () => {...};

最後に

Dart Sassでは名前空間をはじめ、細かなルールの変更・追加が行われました。
新しい手法なので慣れの問題もあると思いますが、個人的には使いづらくなった印象です。
2022年10月にサポートが終了するまでは移行期間とも受け取れるので、より快適な開発環境の構築を模索したいと思います。

39
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?