Windowsでfvmを使って複数バージョンのFlutterを管理する

# はじめに
FVMを使って、Flutterをプロジェクトごとにバージョン管理したくて、FVMを導入しようと思いましたが、いくつか詰まったポイントがありました。
ネットで調べると、Mac側の環境構築の記事はたくさん出てきましたが、Windowsの記事があまり出てこず困ったので、同じく困っている方のお役に立てればと思い記事にしました。

本記事ではインストールから実際にFlutterのプロジェクトで使うまでを説明したいと思います。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [FVMのインストール](#FVMのインストール)
1. [FVMでFlutterをインストール](#FVMでFlutterをインストール)
1. [Flutterプロジェクトごとにバージョンを管理する](#Flutterプロジェクトごとにバージョンを管理する)

<!-- 各チャプター -->
<a id="#FVMのインストール"></a>
# FVMのインストール
まずFVMのインストールします。
インストールの方法は複数ありますが、本記事では`Chocolately`でインストールしたいと思います。
→ FVMのインストールについての[公式ページ](https://fvm.app/docs/getting_started/installation)

### 1. Chocolateryをインストール
`Chocolately`とは、Windows 用のパッケージ管理ソフトウェアです。
以下の記事のインストール方法が大変わかりやすかったので、ご参考にインストールをお願いします。
https://qiita.com/konta220/items/95b40b4647a737cb51aa

### 2. fvmをインストール
`Chocolately`がインストール出来たら、下記のコマンドを実行し、fvmをインストールします。
```
choco install fvm
```

インストール完了後、以下のコマンドを実行し、バージョン情報が表示されればインストールされています。
```
fvm --version
```
<a id="#FVMでFlutterをインストール"></a>
# FVMでFlutterをインストール
FVMを使ってFlutterをインストールしていきたいのですが、すでにFlutterをインストールしている方と未インストールの方で手順が違ってきます。
未インストールの方は「[Flutterをインストール](Flutterをインストール)」の項から始めてください。

### Flutterをインストール済みの場合
Flutterの環境構築済みの場合、おそらく、Flutterのページから`c:src:flutter`にFlutterをダウンロードし、パスを通している方がほとんどかと思います(Windowsで環境構築するとこの説明が多い)
FVMを使う場合、このパスではなく、FVM経由でバージョンを指定してFlutterを使うことになるので一旦この環境を削除します。
**なお、行う場合は以下のことに注意し、問題なければ実行してください。**
**※既存のプロジェクトは現在のFlutter環境のパスを参照しているはずなので、環境を削除すると次回起動時エラーとなります。エラー自体は、プロジェクトでflutterの参照先を変更すれば問題ありません。しかし、開発中のプロジェクトがたくさんあると手間なので、面倒な場合はやめておいた方が無難です。**

では、上記を確認の上、削除する方は削除していきましょう。
まず、コマンドプロンプトで下記のコマンドを実行し、Flutterのパスを確認します。

```
where flutter
```

Flutterの環境構築時、上記で表示されたパスを環境変数に登録したと思うので削除します。
(「Windows 環境変数」で調べると記事が出てくるのでご参考に）
また、ややこしくなるので、上記のパスのフォルダも削除しておいてください。
(削除できない場合はどこかで参照している可能性が大です。PCを再起動したら削除できるようになると思います。)

削除出来たら、もう一度コマンドを実行し、何も見つからなければOK
```
where flutter
```

<a id="Flutterをインストール"></a>
### Flutterをインストール
FVMでFlutterをインストールする前に、どのバージョンがインストールできるか確認します。
お好きなターミナルで下記のコマンドを実行して下さい
```
fvm releases
```

表示されたバージョンの中から好きなバージョンを指定してFlutterをインストールします。
```
fvm install 3.3.5
```

### Flutterのパスを通す
`C:\Users\[サインインユーザー名]\fvm\default\bin`にflutterファイルがあるか確認してください
(FVMでFlutterインストールを実行するとここに置かれるはず）

確認出来たら、環境変数設定で、ユーザーの環境変数のPathに確認できたパスを追加して下さい。
(上記の通りのパスなら以下になるはず）
```
C:\Users\[サインインユーザー名]\fvm\default\bin
```

**※ 上記にない場合は、`where flutter`を実行するとわかるはず。**

追加したら、ターミナルを再起動後、以下のコマンドを実行し、バージョンが出てきたらOK
```
flutter --version
```

<a id="#複数バージョンのFlutterを管理する"></a>
# 複数バージョンのFlutterを管理する
FVMでインストールしたFlutterのバージョンは以下のコマンドで見ることができます
```
fvm list
```

複数インストールしていると、flutterコマンドを使った場合どのバージョンが使われるかという疑問が出てくるかと思いますが、fvmでglobalに設定されているバージョンがデフォルトのバージョンとして使われます。
globalに設定されているバージョンは、`fvm list`と実行したときに横にglobalと表示されます。
(未確認ですが、最初だとないかも？)

globalへの設定は以下のコマンドで行います。
`3.3.0`にはお好きなバージョンを指定して下さい。
`fvm list`にない未インストールのバージョンを指定した場合は、インストールするかどうか聞かれます。
**※ターミナルを管理者権限で起動する必要があります**
```
fvm global 3.3.0
```

無事切替ができたら`flutter --version`を実行するとと切り替えたバージョンが表示されると思います。
また、`fvm list`を実行すると切り替えたバージョンの横にglobalと表示されるはずです。

<a id="#Flutterプロジェクトごとにバージョンを管理する"></a>
# Flutterプロジェクトごとにバージョンを管理する
個別のプロジェクトでバージョン管理をする方法を説明したいと思います。

### プロジェクトにFVMのバージョン管理を導入する
プロジェクトの作成から説明していきます。
**※説明はAndroidStudioでの説明となります**
既存のプロジェクトに導入したい場合は「3.プロジェクトで使用するバージョンを指定する」から実行してください。
#### 1.新規プロジェクトを作成する
AndroidStudioで新規プロジェクトを作成します。
特に説明することはないですが、FlutterのSDKのパスには`C:\Users\[サインインユーザー]\fvm\default`を指定してください。

作成後、ターミナルで`flutter --version`を実行してみてください。
すると、バージョンにはglobalで設定したバージョンが表示されるはずです。
現在の参照はglobalのバージョンとなっているのでこれを変更します。

#### 2.プロジェクトで使用するバージョンを指定する
プロジェクトでバージョンを指定するには`fvm use`というコマンドでバージョンを指定します。
ただ、AndroidStudioのターミナルで実行すると管理者権限ではないため、エラーとなります。
そのため、まず管理者権限でコマンドプロンプトなどのターミナルを起動してください。
そして、以下のコマンドを順番に実行してください
(プロジェクトのフォルダパスと`3.0.0`の部分は任意のものを指定してください。
**本当に切り替わっているかの確認をするため、globalで設定したバージョンと違うものをひとまず設定することをおすすめします。**)
```
cd プロジェクトのフォルダパス
```
```
fvm use 3.0.0
```

実行後、AndroidStudioでプロジェクトを確認すると、プロジェクト直下に`.fvm`フォルダが作成されていると思います。
(出てない方は、AndroidStudioを再起動してみてください）
`.fvm`フォルダを見ると`fvm_config.json`が作成されているはずですが、ここに現在の指定したバージョンが記述されています。

続いて、Flutter SDK pathの参照先をプロジェクトのバージョンに変更します。
以下の通りメニューを遷移して、設定画面を開いていください
`File→Settings→Languages&Framworks→Flutter`
そして、`Flutter SDK path`に以下のパスを設定します。
`プロジェクトのフォルダパス/.fvm/flutter_sdk`

これでプロジェクト個別のFlutterバージョンが指定できました。
**プロジェクトを開いているAndroidStudioのターミナルから**、以下のコマンドを試してバージョンを確認してみてください。
```
flutter --version
```

**globalで設定したバージョンが出たと思います。**
自分がハマったのであえて試してもらいました。
プロジェクト個別に設定しても、`flutter`というコマンドではglobalの設定が参照されるようです。
なので、プロジェクト個別に設定したバージョンを使いたい場合は以下のコマンドのように、`flutter`の前に`fvm`を付けてください。
```
fvm flutter --version
```
すると、`fvm use`で指定したバージョンが出てくると思います。

#### ※`Flutter SDK path`の設定について
未確定の情報なのですが、複数のプロジェクトで`Flutter SDK path`の設定を個別に設定するのは不可能かもしれません。
(やり方知ってたら教えてください）
一つのプロジェクトで`Flutter SDK path`を変えると他のプロジェクトを開いたときに同じパスになってました。
また、あるプロジェクトで`pubspec.yaml`を開いたときに出てくる`Pub get`(下記画像のボタン)を使うと`Flutter SDK path`が勝手に変わってしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475427/3a97779f-6bc0-ab80-f245-86f88ec2ae89.png)

(この動きになったときは、他のプロジェクトの`Flutter SDK path`は変わってなかったです。バージョンを指定したときに`unsafe repository・・・`みたいなログが出ていたのでそれが原因かもしれないです。）

以上のことが正確にどういう動作で原因が何かはわかりませんが、`FVM`でバージョン管理する場合は、AndroidStudioの`Pub get`ボタンを使わず、ターミナルで`fvm flutter`コマンドを使って操作する方がよさそうです。

<a id="#さいごに"></a>
# さいごに
自分が導入時に躓いた点は説明できたかと思います。
ただ、最後に書いたように`Flutter SDK path`の設定まわりと、AndroidStudioの`Pub get`ボタンの動作で不明な点があったので、何かご存じの方いらっしゃったらコメントいただけるとありがたいです。