VSCodeにF#の開発環境を導入する方法

# はじめに

F# の開発環境には主に `Visual Studio` か `Vsual Studio Code` を利用することが多いと思います。
その中でも今回は `Visual Studio Code` の環境構築方法について紹介していこうかと思います。

正直 `Visual Studio` を選択すれば特に何もしなくても普通にインストールするだけで環境構築できてしまうので、圧倒的に楽です。
ただ、`Visual Studio` は基本的に Windows でしか利用できないため、Windows や Mac、Linux などの複数 OS 間で同じ開発環境で開発したい場合には `Visual Studio Code` の方が適しています。

また、チーム開発をする上で各員の利用している OS に囚われることなく開発環境を統一できる点が優れています（開発環境を統一することで享受できるメリットは Visual Studio でも同様のことが言えます）。

と、いうことで今回は `Visual Studio Code` を使って F# 開発をするための `環境構築 + α` を紹介できればと思います。

# プラグイン

`Visual Studio Code` には `プラグイン` と言われる後から導入できる追加機能が多数存在しています。
その中でも `F# 開発` に必要な `プラグイン` を紹介します。

## ionide

`Visual Studio Code` での F# 開発する上でのデファクトスタンダードなプラグインです。
基本的には必ず導入します。
<img width="1022" alt="スクリーンショット 2019-12-14 11.10.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/dabe43dc-521c-d8f0-21f8-04012bdd5d5f.png">

## C#  

上記 `ionide` が依存しているプラグインであるため導入が必須となっています。
<img width="1024" alt="スクリーンショット 2019-12-14 11.15.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/8886205c-8707-b7cd-94d4-2391c2b7adfd.png">

## F# Language Server

このプラグインは必須ではないですが、`.fsx` で開発する際には大いに役立ちます。
F# script でバンバン開発する人は導入しておくと良いでしょう。


<img width="1024" alt="スクリーンショット 2019-12-14 11.24.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/23e81f25-3b40-ba42-ba43-7f1ec8537543.png">

### 🚨注意事項🚨

`F# Language Server` は `ionide` と競合する場合があるので、`.fsx` で開発しない場合には OFF にしておきましょう。
> Disable(Workspace) または 無効にする(ワークスペース) を選択することで、そのプロジェクトに対してのみ機能を OFF にすることが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/6b45811f-c681-7c46-8c7c-890b68b41bb3.png)

## .NET Core Test Explorer

`Unit Test` をイイ感じに実行するのに必要です。
`Unit Test をしていないコードはレガシーコード`、いいね？！

ちなみに[**アドカレ21日目の記事**](https://qiita.com/Midoliy/items/29abc75c296d8cce7137)はこのプラグインを利用して xUnit を利用する方法を紹介する予定です。
<img width="1025" alt="スクリーンショット 2019-12-14 11.20.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/ee3d220b-88e8-c7a5-9a4a-bc073b647bab.png">

# 開発

では実際にプロジェクト作成からビルドまでの流れを紹介していきます。

なお `.NET Core` が既に導入されていること前提に話を進めていきます。
また、コンソールは `Powershell` を利用しています。

## プロジェクト作成

まずは `dotnet` コマンドを利用してプロジェクトを作成します。

```powershell
dotnet new console -lang="F#" -o="SampleProject"
```

これでプロジェクトが作成できたので、`Visual Studio Code` で開きます。

```powershell
code "./SampleProject"
```

## ビルド環境設定

`Visual Studio Code` が起ち上がったら `Program.fs` を開いて見ましょう。
以下のようなデフォルトコードが記述されていると思います。
<img width="1023" alt="スクリーンショット 2019-12-14 11.41.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/fc613a61-a17c-f9d5-a880-7c2bb1fd4743.png">

ここで 1行目 にエラーが発生していますが、これは `ionide` の問題なので気にしないでください。

それでは実際に `build & run` の環境を整えていきましょう。
まずは `F5` を押下してみてください。

すると以下のような選択肢が出てくると思うので、`.NET Core` を選択します。

<img width="1022" alt="スクリーンショット 2019-12-14 11.50.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/81fd0490-8eca-f450-738d-2f07dd0d3e75.png">

次に `launch.json` というファイルが自動生成されるので、右下の `Add Configuration` または `構成の追加` をクリックして、`.NET: Launch .NET Core Console App` を選択します。
<img width="1023" alt="スクリーンショット 2019-12-14 11.52.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/0a212748-3d98-628e-0caf-dfd54cba0bee.png">

<img width="1024" alt="スクリーンショット 2019-12-14 11.54.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/7d817707-af3c-f0a7-0a31-63fdbc4b1ed4.png">

場合によっては、以下のようなエラーメッセージのせいで `Add Configuration` が隠れていることがあるので、エラーメッセージを消してから、上記の手順で構成を追加してください。
<img width="1022" alt="スクリーンショット 2019-12-14 11.58.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/cd646ca9-194d-4c5f-dec6-471fad9a6c38.png">

構成を追加できると 2箇所 ほど手で修正しなければならない箇所が出てきます。
<img width="1141" alt="スクリーンショット 2019-12-14 12.02.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/eef407a8-f20e-741b-f89c-5b017c02d7fe.png">

- `<target-framework>` には、`netcoreapp3.0` と入力します。
    - .NET Core 2.1 を利用している場合には `netcoreapp2.1` を .NET Core 3.1 を利用している場合には `netcoreapp3.1` としてください。
    - もし自分が使っている .NET Core のバージョンがわからない場合、`dotnet --version` コマンドを利用して確認しましょう。

- `<project-name.dll>` には `SampleProject.dll` と入力します。
    - 例えばプロジェクトを `dotnet new console -lang="F#" -o="テスト"` で作成した場合には `テスト.dll` となるので、その時々に適した名称にしてください。

上記を一通り実施すると以下のようになると思います。
<img width="1077" alt="スクリーンショット 2019-12-14 12.10.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/91431e2e-23c2-504c-0a6d-a6bb33f76468.png">

ここまでできたら、再度 `F5` を押下します。

すると以下のようなエラーが表示されると思うので、`Configure Task` または `タスクの構成` を押下して、タスクの構成を追加します。
<img width="1078" alt="スクリーンショット 2019-12-14 12.13.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/8a562000-9d7b-ca8a-0b05-c8395713a93d.png">

<img width="1076" alt="スクリーンショット 2019-12-14 12.18.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/c8228226-53b4-da32-4545-4fa10f08e0de.png">

<img width="1078" alt="スクリーンショット 2019-12-14 12.19.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/27abbe86-4d5d-81bd-d6d1-bc429eb8252c.png">
 
`tasks.json` が追加されたら、特に何も変更せずにもう一度 `F5` を押下してみてください。
正しく設定ができていれば以下のように `Hello World from F#!` が表示されると思います。
<img width="1077" alt="スクリーンショット 2019-12-14 12.20.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/9f1874f8-2eaa-a20c-3b73-a7169e536bf9.png">

これで基本的な設定が完了しました。
通常の開発であれば、以上の設定で問題なく行えると思います。

## おまけの設定

実は上記の `launch.json` では、`標準入力` からの入力を受け取るタイプのデバッグをすることができません。
そこで `launch.json` に以下の 2つ の修正を入れて `標準入力` から値を受け取れるようにします。

- `console` を `internalConsole` から `integratedTerminal` に変更
- `internalConsoleOptions` を `neverOpen` として追加

上記を設定すると `lanuch.json` は以下のようになっていると思います。
<img width="1079" alt="スクリーンショット 2019-12-14 12.31.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/d961c9a4-82e5-0df7-a5c1-1a5e815ca341.png">

これで `標準入力` から値を受け取ることができます。
試しに `Program.fs` を次のように変更してから `F5` で実行してみてください。

```fsharp
let input = stdin.ReadLine()
printfn "input= %s" input
```

すると以下のように入力待機中となるので、何がしかの値を入力してあげると、その値を使った出力をしてくれます。
<img width="1077" alt="スクリーンショット 2019-12-14 12.35.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/0acbf811-c576-bae2-971c-12adc06f3dbe.png">
<img width="1076" alt="スクリーンショット 2019-12-14 12.36.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/14af7c2c-9f27-3478-364f-556373d08f40.png">

この `launch.json` の設定をしてあげないとうまいこと動作しないので気を付けましょう。

## fsファイルを追加する

通常、F# の開発ではモジュールなどを複数のファイルに分割します。
`Visual Studio` で開発している時には気にしないかと思いますが、実際には裏で `.fsproj` ファイルに `.fs` ファイルの情報を追加することでファイル分割の依存関係を解決しているのです。

では `Visual Studio Code` での別ファイルを追加してみましょう。
※以下の方法でうまくできない場合は <a href="#うまくfsファイルを追加できない場合">ここを参照</a>

まずは、プロジェクト名のところで右クリックして、`Add file` を選択します。
<img width="1077" alt="スクリーンショット 2019-12-14 12.42.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/db39404c-87bc-3b76-b2a6-762d24fe9a58.png">

するとファイル名を指定できるので好きなファイル名を入力します。
今回は `Calc.fs` という名前にしました。
<img width="1076" alt="スクリーンショット 2019-12-14 12.46.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/f0962f78-7d21-3346-d47e-46121f12aebb.png">

すると `Calc.fs` というファイルが `Program.fs` の下に追加されたと思います。
<img width="1075" alt="スクリーンショット 2019-12-14 12.57.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/4151f526-23cc-a6d8-aa9d-6a07a0497be2.png">

`F#` はプロジェクト内での順序が非常に重要な言語です。
利用されるファイルは、必ず利用するファイルよりも上位にいなければなりません。

今回で言えば、`Calc.fs` は `Program.fs` の上にないといけないわけです。

`Calc.fs` のところにマウスオーバーすると矢印（⇅）が出てくるので、上向きの矢印（↑）をクリックして、`Calc.fs` を `Program.fs` の上に持ってきます。
<img width="1075" alt="スクリーンショット 2019-12-14 13.02.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/7e840563-83d6-6767-bd85-2a8788f1121a.png">
<img width="1077" alt="スクリーンショット 2019-12-14 13.03.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/8d118018-36ca-fad2-f79e-092ac9b39ca4.png">
 
こうすることによって、`Program.fs` 内で `Calc.fs` のモジュールなどを利用することができるようになります。

それでは実際に、`Calc.fs` 内のモジュールを `Program.fs` で利用してみましょう。

`Calc.fs` はテキトーに以下のようなモジュールを用意します。

```fsharp
module Calc
let add x y = x + y
```

`Program.fs` は以下のように `Calc.fs` のコードを呼び出してみます、

```fsharp
Calc.add 10 20
|> printfn "10 + 20 = %d"
```

それでは実際に実行してみましょう。
以下のような出力がされたら成功です。
<img width="1077" alt="スクリーンショット 2019-12-14 13.11.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/30eb51ae-46ed-5e7a-08a7-a473c21ee2c2.png">

### うまくfsファイルを追加できない場合

環境によっては上記の方法でうまく fs ファイルを追加できないことがあります。
そんな場合には `fsproj` ファイルを直接修正してあげる必要があります。

まず、`Calc.fs` ファイルを作成します。
<img width="1079" alt="スクリーンショット 2019-12-14 13.16.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/b7cdc18f-288b-be79-5a44-2a063cdab106.png">

次に `SampleProject.fsproj` ファイルを直接修正していきます。
`Compile` 要素をコピーします。
<img width="1078" alt="スクリーンショット 2019-12-14 13.20.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/dbe3d728-cab4-b058-8f56-f759229a9aed.png">

それをすぐ下にペーストし、上の方を `Include="Calc.fs"` とします。
<img width="1078" alt="スクリーンショット 2019-12-14 13.24.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/ced4af65-0649-bc28-1f58-1fed98abd138.png">

ここの上下関係がそのまま依存関係となるので、注意しましょう。
これで、`Program.fs` から `Calc.fs` を利用することができるようになります。

## ブレークポイントの設定

`Visual Studio` などの IDE で開発では非常によく利用する機能ですね。
デバッグする際には必ずと言っていいほど利用するこの機能ですが、`Visual Studio Code` でも利用することができます。

まずは、`Program.fs` を以下のように書き換えます。

```fsharp
let answer = Calc.add 10 20
printfn "10 + 20 = %d" answer
``` 

次に、ブレークポイントを作りたい行で `F9` を押します。
すると、行番号の左隣に赤点がつくと思います。
<img width="1077" alt="スクリーンショット 2019-12-14 13.33.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/cd31d2ac-6cf6-b860-87fc-36396b9530ae.png">

その状態で `F5` を押してみましょう。
その行で処理が一時停止してくれるはずです。
<img width="1075" alt="スクリーンショット 2019-12-14 13.35.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/4e5dde8f-a3d6-bdaa-ac4b-966ec3e7698d.png">

`F10` を押すことでステップ実行することもできます。
<img width="1076" alt="スクリーンショット 2019-12-14 21.13.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/5e4110ba-6c77-f1ab-b185-08e110fc919f.png">


このあたりのキーバインドは `Visual Studio` と全く一緒なので、C# や VB などを `Visual Studio` で利用していた方には馴染みが深いと思います。

# おわりに

`Visual Studio Code` は本当に優秀ですね。
今回は紹介していませんが、`F12` で定義へ飛べたり、`Alt + F12` で定義をその行に表示できたりと、`Visual Studio` でよく利用する機能が使えるので助かります。

特に OS に左右されず同一環境を構築できるのが優秀です。
興味がある方はぜひ利用してみてください。