できない.dev

Sass「@use rules must be written before any other rules」の原因と直し方

@use rules must be written before any other rules は、@use を先頭へ移せば直る。
前に置けるのは @forward や変数宣言などだ。
Vite の additionalData でも出る。

公開:

要約

@use の前に別のルールがあると、Dart Sass は @use rules must be written before any other rules で止まる。
sass 1.107.1 では次のように出て、終了コードは 65 になる。

Error: @use rules must be written before any other rules.
  ╷
4 │ @use "vars";
  │ ^^^^^^^^^^^
  ╵
  rule.scss 4:1  root stylesheet

@use をファイルの先頭へ移せば直る。@use の前に置いて通るのは、@forward、変数の宣言、コメント、@charset である。@forward も同じ規則に従い、ルールの後ろでは @forward rules must be written before any other rules. と出る。

解決策

1. @use を先頭へ移す

@use "vars";
@use "sass:math";
 
.a {
  color: vars.$color;
  width: math.div(4, 2) * 1px;
}

読み込むモジュールを変数で設定するときだけは、変数の宣言を前に置ける(公式ドキュメント(新しいタブで開く))。

$size: 2px;
@use "lib" with ($size: $size);

2. @import を @use の後ろへ移す

@use "vars"; の下に @import "old"; を書く順番なら、エラーは消える。@import には非推奨の警告が出続けるので、消す手順は @import rules are deprecated の記事に従う。

3. @mixin や @function を後ろへ移す

@use をすべて書いた下に定義を置く。

4. Vite の additionalData を直す

additionalData には @use か変数の宣言だけを書く。
Vite 8.3.5 で、次の設定はファイル側に @use "sass:math"; があってもビルドが通った。

export default {
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "/src/vars" as *;\n`,
      },
    },
  },
}

パスは /src/vars のようにプロジェクトのルートから書く。src/vars と書くと Can't find stylesheet to import になった。additionalData は読み込むスタイルごとに足されるので、スタイルのルールを書くと出力に重複する(公式ドキュメント(新しいタブで開く))。

よくある原因

  1. スタイルのルールの後ろに書いている。.a { color: red; } の下に置くと、@use "sass:math" のような組み込みモジュールでも止まる。
  2. @import の後ろに書いている。
    移行の途中で、古い @import の下に @use を足すと起きる。@import url("foo.css") のような CSS の読み込みでも同じである。
  3. @mixin・@function・@media・@if の後ろに書いている。
    定義だけで何も出力しない @mixin でも止まる。
  4. Vite の additionalData がファイルの先頭にルールや @import を足している。
    自分のファイルの 1 行目が @use でも止まる。
    足された行の分だけ行番号がずれるので、1 行目の @use が src/a.scss 2:1 と表示される。