🐫

Dart Sass でCSS変数を定義するとコメントの扱いがおかしくなる問題

2023/06/09に公開

環境

$ node-sass -v
node-sass   9.0.0   (Wrapper)   [JavaScript]
libsass     3.5.5   (Sass Compiler) [C/C++]

$ sass --version
1.63.2 compiled with dart2js 3.0.3

こう書くと壊れる

A と B のコメント残して、

cat <<'EOF' > a.sass
body
  --foo: blue       // A
  color: var(--foo) // B
EOF
node-sass --output-style expanded a.sass
sass a.sass

それを CSS に変換すると、

body {
  --foo: blue;
  color: var(--foo);
}
body {
  --foo: blue // A;
  color: var(--foo);
}

ブラウザで読み取れない CSS が生成される。

node-sass ではコメントが取り除かれていたのに対し、Dart Sass では // A が残っているためブラウザは CSS を正しく読み取れない。これは sass 形式で書く人のほとんどがはまりそうに思えるのだが、ググっても誰も踏んでないのが不思議である。

捻り出した回避策: @mixin で包む

cat <<'EOF' > a.sass
=defvar($key, $val)
  --#{$key}: #{$val}

body
  +defvar(foo, blue) // A
  color: var(--foo)  // B
EOF

node-sass --output-style expanded a.sass
sass a.sass
body {
  --foo: blue;
  color: var(--foo);
}
body {
  --foo: blue;
  color: var(--foo);
}

試行錯誤の末に @mixin の中に入れるとコメントが除去されることに気づいた。が、こんなことしないといけないとか絶対におかしい。

別の回避策: コメントマークを変更する

こちらの方法

https://github.com/sass/sass/issues/2770

では ///* */ に変更することで不整合を回避している。

cat <<'EOF' > a.sass
body
  --foo: white /* a */
EOF
node-sass --output-style expanded a.sass
sass a.sass
body {
  --foo: white /* a */;
}
body {
  --foo: white /* a */;
}

溜息が出るような対処法である。

Discussion