Azure Functions Pack を試してみた。


[TsuyoshiUshio@github](https://qiita.com/TsuyoshiUshio@github) さんがSNSで紹介してたツイートを見つけて、ワーッとなったので試してみた。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">You can grab it on npm now: npm i -g azure-functions-pack@next<br><br>Docs here: <a href="https://t.co/poFhvfmRu8">https://t.co/poFhvfmRu8</a><br><br>Will move to master later this week</p>&mdash; How Chris Functions (@crandycodes) <a href="https://twitter.com/crandycodes/status/920110656191205376?ref_src=twsrc%5Etfw">2017年10月17日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


npmパッケージを多数使っているFunctionだと起動時にそれらのファイルを読み込むため、起動に時間がかかる。で、このツールを使うと、それらを１つのJSファイルにパックできるので、起動時間を短縮できるらしい。Httpトリガーなんかでパフォーマンスを良くしたい場合なんかに使えそうだ。

# 準備

## npm パッケージをインストール

```
$ npm install -g azure-functions-core-tools
$ npm install -g azure-functions-pack
```



## サンプルコード

Githubに置いておきました。

```
$ git clone git@github.com:satoryu/azure-funcpack-sample.git
```

BlobトリガーでCSVファイルをパースするだけの簡単なFunctionです。
CSVを扱うために[csv](https://www.npmjs.com/package/csv)に依存しています。

試しにローカルで動かすとこんな感じ。BlobにアップロードしたCSVファイルをそのまま表示させてるだけ。

```
[10/17/17 4:41:23 PM] Found the following functions:
[10/17/17 4:41:23 PM] Host.Functions.ImportCSVfile
[10/17/17 4:41:23 PM]
[10/17/17 4:41:23 PM] Job host started
[10/17/17 4:41:26 PM] Host lock lease acquired by instance ID '000000000000000000000000FB88AAF3'.
[10/17/17 4:43:58 PM] Function started (Id=d2379990-ae49-4e79-92f2-a0068ae1ac25)
[10/17/17 4:43:58 PM] Executing 'Functions.ImportCSVfile' (Reason='New blob detected: uploaded/sample.csv', Id=d2379990-ae49-4e79-92f2-a0068ae1ac25)
[10/17/17 4:43:58 PM] [ [ 'Name', ' Address' ],
[10/17/17 4:43:58 PM]   [ 'Taro Rakuten', ' taro@rakuten.com' ],
[10/17/17 4:43:58 PM]   [ 'Hanako Rakuten', ' hanako@rakuten.com' ] ]
[10/17/17 4:43:58 PM] Function completed (Success, Id=d2379990-ae49-4e79-92f2-a0068ae1ac25, Duration=357ms)
[10/17/17 4:43:58 PM] Executed 'Functions.ImportCSVfile' (Succeeded, Id=d2379990-ae49-4e79-92f2-a0068ae1ac25)
```

# デプロイ

デプロイの方法は２つある。

1. 予めpackして、funcコマンドでデプロイ
2. git からデプロイ


## 1. packしてからデプロイ

`funcpack pack` サブコマンドでFunctionをpackしてみる。Functionのディレクトリではなく、Functionアプリのルートで実行する。例えば、上のサンプルコードの場合、git clone したリポジトリのトップで実行する。

```
$ funcpack pack ./
info: Generating project files/metadata
info: Webpacking project
info: Complete!
```

これで終了。
実行後に`.funcpack` ディレクトリが作成されているので、その中に入り、`func` コマンドでデプロイする。

```
$ funcpack pack ./
$ cd .funcpack/
$ func azure functionapp publish ${your_function_app_name}
```


## 2. git からデプロイ

git でデプロイする場合、環境変数を設定することでデプロイ時に`funcpack pack`を実行してくれる。

### 環境変数

git でデプロイする場合は、App Settings に下記の`SCM_USE_FUNCPACK` 環境変数に値を１として設定する必要がある。

![tatzfunctions_-_Microsoft_Azure.png](https://qiita-image-store.s3.amazonaws.com/0/3662/5840be18-290d-ae56-6e9a-956e60fe05af.png "tatzfunctions_-_Microsoft_Azure.png")


### いざ、デプロイ！

下記のように`npm install ` を実行後、`funcpack pack`が実行されている

```
$ git push azure master
Counting objects: 25, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (23/23), done.
Writing objects: 100% (25/25), 17.38 KiB | 2.90 MiB/s, done.
Total 25 (delta 2), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'e4e41e7d29'.
remote: Generating deployment script.
remote: Running deployment command...
remote: Handling function App deployment.
remote: Using funcpack to optimize cold start
remote: Copying repository files to local storage
remote: 10 File(s) copied
remote: Restoring npm packages in "D:\local\Temp\8d51582848aa8df"
remote: .....
remote: importcsvfile@1.0.0 D:\local\Temp\8d51582848aa8df\ImportCSVfile
remote: npm WARN importcsvfile@1.0.0 No repository field.
remote: `-- csv@1.1.1
remote:   +-- csv-generate@1.0.0
remote:   +-- csv-parse@1.2.4
remote:   +-- csv-stringify@1.0.4
remote:   | `-- lodash.get@4.4.2
remote:   `-- stream-transform@0.1.2
remote:
remote: info: Generating project files/metadata
remote: info: Webpacking project
remote: info: Complete!
remote: KuduSync.NET from: 'D:\local\Temp\8d51582848aa8df' to: 'D:\home\site\wwwroot'
remote: Copying file: '.gitignore'
remote: Copying file: 'host.json'
remote: Copying file: '.funcpack\index.js'
remote: Copying file: '.funcpack\original.index.js'
remote: Copying file: 'ImportCSVfile\function.json'
remote: Copying file: 'ImportCSVfile\index.js'
remote: Copying file: 'ImportCSVfile\package-lock.json'
remote: Copying file: 'ImportCSVfile\package.json'
remote: Copying file: 'ImportCSVfile\readme.md'
remote: Copying file: 'ImportCSVfile\sample.dat'
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Syncing 2 function triggers with payload size 288 bytes successful.
remote: Deployment successful.
```


# おまけ

Azure Functionのロゴは絵文字で表現できるそうです。

```
< ⚡ >
```

それでは、楽しいFunctionライフを！
See you!

# 参考

* [Azure/azure-functions-pack at dev](https://github.com/Azure/azure-functions-pack/tree/dev)
* [Azure/azure-functions-cli: Command line tool for Azure Function](https://github.com/Azure/azure-functions-cli)