netlify上にnuxt + netlify functionsで公開する

# やること

Netlify functionsを使って、ほぼ静的サイトにちょっとだけサーバーサイド欲しい気もする的なことをできるようにしました。



# できあがりのディレクトリ構成

```
[root] ─ [assets/pages など、nuxtのディレクトリ]
       ├ [functions] ← netlify functionのコードファイルを置くために作成
       │     ├ [api] ← この中にコードファイルを置く
       │     └ [(dist)] ← ビルド用。localでは作らない
       ├ nuxt.config.js / yarn.lock(package.lock) など設定ファイル
       ├ package.json ← Nuxtの実行コマンドに修正を加える
       └ netlify.toml ← netlifyの実行コマンドを記載
```


# やってみよう

## nuxt テンプレートの準備

なにはともあれ、Nuxtテンプレートをインストール。
途中で聞かれる「Deployment target」はNetlifyを使う（静的ホスティングを使う）のでstaticで。 

```
$ yarn create nuxt-app myproject
（⇒　`create-nuxt-app v3.2.0` でインストール終了。）
```

netlify functionsを使うので、netlify-lambdaをインストール

```
$ yarn add netlify-lambda
```


## とりまfunctionの作成

```
$cd myproject
$mkdir functions/api
```
とりあえず、helloって言ってみよう。

```javascript:functions/api/hello.js
exports.handler = async (event, context) => {
  return {
    statusCode: 200,
    body: "Hello, World"
  }
}
```


## 実行コマンドの設定

rootにnetlify.tomlファイルを作成

```netlify.toml
[build]
  command = "yarn build && nuxt export"
  functions = "functions/dist"
  publish = "dist"
```


```package.json
  "scripts": {
    "dev": "nuxt && netlify-lambda serve functions/api",
    "build": "nuxt build && netlify-lambda build functions/api",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "dev:functions": "netlify-lambda serve functions/api"
  }
```

## ローカル環境で実行
```
$yarn dev
$yarn dev:functions
```
⇒
`https://localhost:3000` でnuxt
`http://localhost:9000/.netlify/functions/hello` でfunctionsのhello.js が実行される。（下2つは設定したディレクトリ構成/実行ファイル）


## Netlifyへデプロイ

というか、GitHub(を使ってます)にpush。
っていうあたりは、どこにでも書いてあるので省略。
Netlifyのアカウント作って、GitHubのアカウント＆レポジトリ作って、
ローカルのファイルをpushしたら、自動でNetlifyにデプロイ。

`https://xxxduuuummmmyyyyyxxx.netlify.app/` → Nuxt app
`https://xxxduuuummmmyyyyyxxx.netlify.app/.netlify/functions/hello` → hello.js

無事表示されました～

# エラー事例

わからなくていっぱいウロウロしました。

## ディレクトリ構成

エラー意訳：serve/build 用それぞれ別のフォルダにしてね！

### やったこと

```
ディレクトリ構成
[root] ─ [assets/pages など]
       ├ [functions]
       └ 各種設定ファイル
```

```netlify.toml
[build]
  command = "yarn buildy"
  functions = "functions"
  publish = "dist"
```

```package.json
  "scripts": {
    "dev": "netlify-lambda serve functions && nuxt",
    "build": "netlify-lambda build functions && nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
  }
```

### エラー文

```
Error:
      netlify-lambda Error: Function source folder (specified in netlify-lambda serve/build command) and publish folder (specified in netlify.toml)
      should be different. They are both set to C:\Users\hogehoge\myproject\functions.

      This is a common mistake for people switching from Netlify Dev to netlify-lambda. For an easy fix, change your functions key inside netlify.toml to something else, like "functions-build".
      You will then need to build your functions to that directory before they will work locally and the built functions will also need to be pushed to your repo.
```

### 対処

ディレクトリ構成＆コマンド設定の変更

## （エラーとちょっと違うけど）ローカル実行

エラー（じゃないけど）起こったこと：nuxtかfunctions片方だけしか実行されない

### やったこと

```package.json
  "scripts": {
    "dev": "netlify-lambda serve functions && nuxt",
    "build": "netlify-lambda build functions && nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
  }
```

って書いたし、これでfunctionsの実行も、nuxtの実行もされるよね～

```
$yarn dev
```
...されませんでした。
先に書いてあるコマンドのみ実行されます。
※上記だと、functionsだし、`"nuxt && netlify-lambda serve functions"` だと、nuxtだし。

### 対処

上記に記載してあるとおり、`package.json`のコマンドに`dev:function`を追加して、2つ平行して実行。


## Netlifyにdeploy　その1

エラー意訳：distディレクトリが無いぜよ！

### やったこと

nuxtテンプレートに一緒に入っている`.gitignore`は`dist`ディレクトリをgit管理外にしています。
＆中身は空なので、push対象外になる（で表現あってるのか？）になります。
その状態でgithubにpushすると

### エラー文

```
Failed during stage 'building site': Deploy directory 'dist' does not exist
```
とエラーがでます。（ん？わたしだけ？？）

### 対処

function用なのか、nuxt用なのか、どっちのdistだろ～～？？と疑問を疑問のままにして対処しました。

Nuxtテンプレートで落ちてくる`.gitignore`ファイルの70行目付近をコメントアウト。
```.gitignore
# Nuxt generate
# dist
```

`.gitkeep`ファイルの作成

```
[root] ─ [dist]
            └ .gitkeep ← 作成
```

※ functions側のdistはローカル環境で実行で中身作成されたっぽい。


## （エラーとちょっと違うけど）Netlifyにデプロイ　その2

起こったこと：デプロイしたけど、Netifyが準備した404ページがドメインルートでも表示される。
デプロイファイルをダウンロードしてみたら、空っぽ。

### やったこと

Netlifyにデプロイ=ssrではなく、静的ホスティング。
そして、spaモードで実行。

nuxtのドキュメント（https://ja.nuxtjs.org/faq/netlify-deployment/）には
下記が書いてあります。（'20/8/19現在）

```
SPA モードで生成されたサイトの場合

ブランチをデプロイする: master もしくはデプロイしたいブランチ
ビルドコマンド: npm run build
公開ディレクトリ: dist
```

この通りの設定を行う。

### 対処

コマンドを`yarn build && nuxt export` に書き換え。
（注意文がでたので、　本当は　`yarn build && nuxt generate`がよさげ。）
こちらで、デプロイしたアプリを確認することができました。


## （エラーとちょっと違うけど）Netlifyにデプロイ　その3

起こったこと：デプロイしたけど、Netifyが準備した404ページがドメインルートでも表示される。
デプロイファイルをダウンロードしてみたら、空っぽ。
(その1と同じやないかい！)

### やったこと

上記のコマンド変更をNetlifyの管理画面に設定。tomlファイルには記載してなかった。。。

### 対処

tomlファイルを直そう。

```netlify.toml
  command = "yarn build && nuxt export"
```

# 参考
https://note.com/shimakaze_soft/n/ncee10d32fe89
https://qiita.com/mikakane/items/d643d31790293a7df854
https://qiita.com/nishinoshake/items/f42e2f03663b00b5886d