Azure Functions Core Tools v3.x を使ってローカル関数プロジェクト開発をする方法

# はじめに

Azure Functions のローカル関数プロジェクトを利用した開発方法については、公式サイトの「**[Azure Functions Core Tools の操作](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#create-a-local-functions-project)**」で詳しく紹介されています。

このページの通り進めることで Azure Functions Core Tools のバージョンが **`v2.x`** ではうまく動作させることが可能となっていますが、**`v3.x`** ではうまく動作しません。
// Node.js 13.x 以降を利用している場合に限る

また、Azure Functions は F# に対応しているにも関わらず、Azure Functions Core Toolsを使って **F# のローカル関数プロジェクトを作成することができません**。

そこで今回は **(1) Azure Functions Core Toolsv3.x を利用** しつつ、**(2) F# でローカル関数プロジェクト開発するための方法** について紹介していきたいと思います。


## 前提条件

筆者の動作環境は以下のようになっています。

| 名称 | バージョン |
|---|---|
| Windows 10 64bit | 1903 |
| Visual Studio Code | 1.46.1 |
| .NET Core | 3.1.301 |
| node | 14.1.0 |
| npm | 6.14.5 |

バージョンが更新されることで、今回の対応が不要になる可能性が高まると思います。


# Azure Functions Core Tools v3.x の導入

以下のコマンドを利用して Azure Functions Core Tools v3.x をインストールします。

```powershell:powershell
npm install -g azure-functions-core-tools@3 --unsafe-perm true
```

すると以下のようにダウンロードが完了していないにも関わらず、インストール処理が終了してしまうと思います。

```powershell
# <中略>
attempting to GET "https://functionscdn.azureedge.net/public/3.0.2534/Azure.Functions.Cli.win-x64.3.0.2534.zip"
[------------------] Downloading Azure Functions Core Tools+ azure-functions-core-tools@3.0.2534
updated 6 packages in 1.289s
```

そこで以下のコマンドを実行し、azure-functions-core-tools に unzipper@0.10.7 をインストールします。

```powershell:powershell
cd $env:AppData/npm/node_modules/azure-functions-core-tools
npm install unzipper@0.10.7
node .\lib\install.js
```

> **[参考 Issue: Any 'func' command does not work #1804](https://github.com/Azure/azure-functions-core-tools/issues/1804)**

すると無事 Azure Functions Core Tools v3.x がインストールされます。
これでめでたく **`func`** コマンドが利用できるようになりました。


# F# でローカル関数プロジェクトを作成する

通常、func init コマンドを利用することでローカル関数プロジェクトを作成することができます。
2020/06/23 現在、C# / Java / JavaScript / TypeScript / PowerShell / Python の6言語についてはオプションを指定することでプロジェクトを即座に作成することができます。

**そう、F# を除くすべての言語が対応しているのです！！**
// Microsoft、そういうトコやぞ

では F# はどうすればよいのかというと、仕方がないので C# のプロジェクトを修正するしかありません。

まずは以下のコマンドでローカル関数プロジェクトを作成します。

```powershell:powershell
func init SampleFuncProj
```

すると以下のような選択肢が現れるので、**dotnet** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/58c5f093-3192-b5b7-0ae1-a097d7b09df0.png)

実行が完了するとローカル関数プロジェクトができあがります。
これを VSCode で起動します。

```powershell:powershell
code ./SampleFuncProj
```

VSCode 上では次のような構成になっていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/24d0ef59-6764-ba85-3d13-bbf572bcff41.png)

次に SampleFuncProj **.csproj** を SampleFuncProj **.fsproj** にリネームします。
そして SampleFuncProj.fsproj 内の以下の箇所を書き換えます。

```xml:SampleFuncProj.fsproj
<!-- <None Update="host.json"> --> 10行目あたりのコード
     <None Include="host.json">
```

> **[参考 Issue: Host.json file in missing #1963](https://github.com/Azure/azure-functions-core-tools/issues/1963)**

修正後は以下のようになっていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/eaf6da39-562d-5dd8-701b-00471350409f.png)

これで F# 用のローカル関数プロジェクトが完成しました！


# おまけ：F# のローカル関数プロジェクトで Hello, World してみる

fsproj を Visual Studio で開くことで C# と同じように開発できるのですが、今回は VSCode を利用しての開発方法について紹介しておきます。
hello.fs というファイルを作成し、SampleFuncProj.fsproj を以下のように修正しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/d42b62c7-d624-7f54-658f-3092d4a5d08e.png)

※ファイルの追加については ionide を利用することで、fsproj に対象ファイルの情報が自動で反映されるのでそちらを利用する方が良いと思います。


次に hello.fs を以下のようにします。

```fsharp:hello.fs
module Hello

open Microsoft.AspNetCore.Mvc
open Microsoft.Azure.WebJobs
open Microsoft.Azure.WebJobs.Extensions.Http
open Microsoft.AspNetCore.Http

[<FunctionName("hello")>]
let run ([<HttpTrigger(AuthorizationLevel.Function, "post", "get", Route = null)>] req: HttpRequest) =
    OkObjectResult "Hello, World" :> ActionResult
```

最後に以下のコマンドを実行することで、Azure Functions をローカル実行することができます。

```powershell:powershell
func start --build
```

以下のエンドポイントにアクセスすることで実行することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/1a061b61-4c2e-ea7d-3a00-e3166343db93.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/9086fb6a-5644-dd6d-3e72-c5300ee6cfbe.png)


## おまけのおまけ

余談ですが VSCode に Azure Functions の拡張機能を入れているとローカル関数プロジェクトを開いたときに以下のようなメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/8336560a-41d8-6587-db91-0e0ae37ac5ca.png)

これで **Yes** を選択してあげると、**F5** でデバッグ実行が可能となります。

**もちろんブレークポイントを設定してステップ実行をすることも可能です。**

もし VSCode で Azure Functions の開発をする際には是非利用してみてください。

【参考画像】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/b3f0c427-4021-31c1-3930-4521984389f9.png)