【Sass】required parameters must precede optional parameters エラーの原因と対処

Sassで関数やMixinを定義したとき、「required parameters must precede optional parameters(必須引数は省略可能な引数より前に置く必要がある)」というエラーが出ることがあります。これは引数の並び順に関するエラーです。この記事では正確な原因と直し方、そして最新のDart Sassでは挙動が変わっている点まで解説します。

この記事の結論:デフォルト値つきの引数を、デフォルト値のない引数より前に置くとこのエラーになります。直し方は必須引数を先、デフォルト値つきを後に並べ替えるだけです。なお最新のDart Sassではこの制約は撤廃されており、エラーは出ません(出るのは Ruby Sass や LibSass / node-sass などの古いコンパイラです)。
スポンサーリンク

エラーの原因

引数にデフォルト値($x: 値)を付けると「省略可能(optional)」になります。古いSassコンパイラでは、省略可能な引数は必ず必須引数より後ろに置くルールがありました。これを破ると、このエラーが出ます。

エラーになる例(デフォルト付きが先)
// NG: $a がデフォルト付き(省略可能)なのに、必須の $b より前にある
@mixin example($a: 10px, $b) {
  margin: $a $b;
}
// → 古いコンパイラで required parameters must precede optional parameters
「デフォルト値の有無」がポイントです。@mixin example($x, $y) のようにどちらもデフォルト値が無ければ両方とも必須なので、この順番ではエラーになりません。エラーになるのは、デフォルト値つきの引数がデフォルト無しの引数より前にあるときだけです。

対処法:必須引数を先に並べ替える

解決はシンプルで、デフォルト値のない(必須の)引数を先に、デフォルト値つきの引数を後ろに並べ替えます。これはすべてのコンパイラで安全に動く書き方です。

OK: 必須を先・デフォルト付きを後
// 関数
@function example($required, $optional: 10px) {
  @return $required + $optional;
}

// Mixin
@mixin example($required, $optional: 10px) {
  margin: $required $optional;
}
関数やMixinの基本的な定義方法は関数を定義する方法、Mixinの実例はmixinで三角形を作成する方法で解説しています。

最新のDart Sassではエラーにならない

重要な補足です。現在の標準であるDart Sassでは、この制約が撤廃されています。デフォルト値つきの引数を前に置いても、エラーや警告なくコンパイルできます(Dart Sass 1.101で確認)。

Dart Sassでは通る(が非推奨ではある)
@function f($a: 10, $b) {
  @return $a + $b;
}

.x { y: f(1, 2);   } // 3  (位置で順に a=1, b=2)
.y { z: f($b: 5);  } // 15 (a は既定の10)
このエラーが今も出る場合、Ruby Sass や LibSass(node-sass)などの古いコンパイラを使っている可能性が高いです。node-sass は開発終了済みのため、可能ならDart Sass(sass パッケージ)への移行もあわせて検討してください。

名前付き引数で順序を気にしない

呼び出し側で名前付き引数を使うと、定義の並び順に関係なく値を渡せます。引数が多いMixinでは可読性も上がります。

名前付き引数で呼び出す
@mixin box($required, $optional: 10px) {
  padding: $required $optional;
}

.a {
  @include box($optional: 20px, $required: 5px); // 順番を入れ替えてもOK
}

よくある質問(FAQ)

Qこのエラーはどんなときに出ますか?
A関数やMixinの定義で、デフォルト値つきの引数を、デフォルト値のない引数より前に置いたときです。必須引数(デフォルト無し)を先に並べ替えれば解決します。
Qデフォルト値が無い引数を2つ並べてもエラーになりますか?
Aなりません。@mixin m($x, $y) のようにどちらも必須なら順番は自由です。エラーになるのは、デフォルト値つき(省略可能)の引数が、必須引数より前にある場合だけです。
QDart Sassなのにエラーが出ません。仕様ですか?
Aはい。最新のDart Sassではこの制約が撤廃されており、エラーになりません。このエラーが出る場合は、Ruby Sass や LibSass(node-sass)などの古いコンパイラを使っている可能性があります。
Q並べ替えられない事情があります。どうすれば?
A呼び出し側で名前付き引数@include box($required: 5px) など)を使えば、定義の順番に関係なく値を渡せます。ただし定義自体は必須引数を先にするのが最も安全です。

まとめ

このエラーへの対処を整理します。

  • 原因はデフォルト値つきの引数が必須引数より前にあること
  • 直し方は必須引数を先・デフォルト付きを後に並べ替えるだけ
  • デフォルト値が無い引数同士なら順番は自由(エラーにならない)
  • 最新のDart Sassではこの制約は撤廃済み(出るのは古いコンパイラ)
  • 順序を気にしたくないときは名前付き引数で呼び出す

関連として、関数を定義する方法mixinで三角形を作成する方法数値をパーセンテージに変換する方法もあわせて読むと、Sassの関数・Mixinの理解が深まります。