🐕

miseでFlutterバージョンを固定する:VSCodeとターミナルのバージョン不一致を解消

に公開

背景

最近はFlutter開発をしています。その中でFlutterのバージョン管理について躓いたので、問題と解決方法をまとめておきます。

遭遇した問題

担当しているプロジェクトでは、miseでFlutterのバージョンを管理しています。Flutterのバージョンアップのタイミングで、ターミナルからは問題なくアップデートされているのに、VSCodeからの実行では古いバージョンのままという事象に遭遇しました。

原因は、VSCodeのsettings.jsonに、以下のようにバージョンを含むSdkへのパスが含まれており、こちらのパスが更新できていない事でした。

{
  "dart.flutterSdkPath": "~/.local/share/mise/installs/flutter/3.29.2-stable"
}

ちなみに上記は、ユーザーの設定として指定されていました。おそらく開発開始当初に指定したのだと思いますが、すっかり失念していました。問題に遭遇したタイミングでは、miseでバージョン指定していると思い込んでおり、VSCodeは別のところで設定されているとは思わず、理解するまでに時間がかかりました。

また、プロジェクトではSdkの指定はされておらず、これも気づくまでに時間がかかった要因のひとつでした。

解決方法

VSCodeでmiseと同じバージョンを使うには、.vscode/settings.jsonに設定を追加する必要があります。

Flutter SDKのパスを直接指定(推奨)

最も安定した方法は、Flutter SDKのパスを直接指定することです。

{
  "dart.flutterSdkPath": "~/.local/share/mise/installs/flutter/3.35.2-stable"
}

この方法だとFlutterのバージョンを更新するたびにsettings.jsonも書き換える必要があるという欠点はありますが、後述するdart.flutterSdkPathが優先される問題や、mise trustの実行忘れによる問題を回避できるため、結果が安定します。

チーム開発では、直接パスを指定した.vscode/settings.jsonをリポジトリにコミットしておくと良さそうです。

dart.getFlutterSdkCommandを利用する方法

結論としておすすめはできませんが、dart.getFlutterSdkCommandという設定を使う方法も検討しました。

{
  "dart.getFlutterSdkCommand": {
    "executable": "mise",
    "args": ["where", "flutter"]
  }
}

この設定により、VSCodeはmise where flutterコマンドを実行し、miseが管理しているFlutterのパスを動的に取得します。miseでバージョンを変更すれば、VSCodeも自動的に追従するため、miseだけでバージョン管理が完結します。

この指定方法は、今年の1月にマージされており、比較的新しい機能のようです。

しかし、実際に使ってみると以下の問題に直面しました。

dart.flutterSdkPathが優先される問題

設定を調整している中で、dart.getFlutterSdkCommandがうまく効かない事がありました。
原因はおそらく、ユーザー設定にdart.flutterSdkPathが残っていたことです。
基本的にはプロジェクトの設定がユーザー設定よりも優先されますが、dart.flutterSdkPathで明示的なパスが指定されている場合は、dart.getFlutterSdkCommandよりも優先されてしまうようです。
ユーザー設定のdart.flutterSdkPathを削除するとうまく機能しました。

公式ドキュメントには、明示的にdart.getFlutterSdkCommandとの関係について書かれているわけではないですが、dart.flutterSdkPathが優先されるという記載があります。

この動作により、プロジェクトの設定よりも個人の設定(ユーザー設定)がどこかで追加されてしまうと、そちらが優先されてしまうという問題があります。

mise trustが必要な環境での問題

また、mise trustを必要とする環境(例えばgit worktreeなどで頻繁にプロジェクトのディレクトリを変えた場合など)では、これを実行しないと正しい結果を得られません。
そして、この問題は気づきづらく、原因を特定するまでに無駄に時間をかけることになってしまいました。

これらの問題を踏まえ、最終的にはFlutter SDKのパスを直接指定する方法が安定していると判断しました。

まとめ

VSCodeでmiseと同じFlutterバージョンを使うには、.vscode/settings.jsonにFlutter SDKのパスを直接指定する方法が最も安定しました。

バージョン更新のたびにsettings.jsonも書き換える必要がありますが、dart.getFlutterSdkCommandを使う方法では、設定の優先順位の問題やmise trustの実行忘れにより結果が安定しなかったため、直接パスを指定する方法に落ち着きました。

参考

Discussion