NuxtのSSRでfirebaseにデプロイしたときの備忘録

#初期設定
##手順１
firebase CLIインストールをインストールして初期化する

```
npm install firebase-tools
```
```
firebase init
```

##手順2
FunctionsとHostingと後は必要なものを選択して次へ

```
? Are you ready to proceed? Yes
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) Database: Deploy Firebase Realtime Database Rules
 ( ) Firestore: Deploy rules and create indexes for Firestore
 ( ) Functions: Configure and deploy Cloud Functions
 ( ) Hosting: Configure and deploy Firebase Hosting sites
 ( ) Storage: Deploy Cloud Storage security rules
```

##手順3
publicを選択(Enter)

```
? What do you want to use as your public directory? (public)
```

##手順4
Noを選択

```
Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
```

#firebase.jsonを設定
firebase.jsonを開いて下記のように設定する。

``public``　firebase hostingにデプロイするフォルダーを指定
``rewrites``　リライトルールを追加して Firebase にデプロイする関数にアクセスできるようになる。

```/firebase.json
{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "public",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "**",
        "function": "ssr"
      }
    ]
  }
}
```
#functionsを記述
元から書いてあるものを削除して以下を記述。

``nuxtConfig`` nuxt.config.jsを使えるようにする。
``debug`` 開発中はエラー文が分かるようにしておく、本リリース時はfalseにする。

```/functions/index.js
const functions = require("firebase-functions");
const { Nuxt } = require("nuxt");
const nuxtConfig = require("./nuxt.config.js");

const config = {
  ...nuxtConfig,
  dev: false,
  debug: true,
  buildDir: "ssr",
};

const nuxt = new Nuxt(config);

exports.ssr = functions.https.onRequest(async (req, res) => {
  await nuxt.ready();
  nuxt.render(req, res);
});
```

#package.jsonを設定
依存関係をすべて記述する。
ルートディレクトリにある**/package.json**のdependenciesをコピー&ペースト。
```node``` が10以降だとfirebaseが**Blazeプラン**以上じゃないとエラーをだす。

```/functions/package.json
{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "10"
  },
  "main": "index.js",
  "dependencies": {
    "@nuxtjs/axios": "^5.12.5",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/pwa": "^3.3.5",
    "@nuxtjs/style-resources": "^1.0.0",
    "cookieparser": "^0.1.0",
    "core-js": "^3.8.3",
    "firebase": "^8.2.7",
    "firebase-admin": "^9.5.0",
    "firebase-functions": "^3.6.1",
    "js-cookie": "^2.2.1",
    "nuxt": "^2.14.12",
    "nuxt-svg-loader": "^1.2.0",
    "vue-nl2br": "^0.1.2",
    "vuex-persistedstate": "^4.0.0-beta.3"
  },
  "devDependencies": {
    "firebase-functions-test": "^0.2.0",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-prettier": "^3.3.1",
    "node-sass": "^4.14.1",
    "prettier": "^2.2.1",
    "sass-loader": "^10.1.1"
  },
  "private": true
}
```

###依存関係をインストールする
```
cd functions && npm install && cd ../
```


#nuxt.config.jsを修正
デプロイ前にエラーを出すため下記のように変更しておく。

```js:/nuxt.config.js
// export default {}
module.exports = {}
```

#buildコマンドを修正
デプロイがしやすくなるように設定しておく。

```npm run build```をしたときにfunctionsに``.nuxt/dist``と``.nuxt.config.js``コピーするようにしておく。

パフォーマンスを高めるために``functions/ssr/dist/client``と``static``を先ほどfirebase.jsonで指定したディレクト、ここでは**「public」**にコピーする。
dist/clientはクライアント側に配信するものなので上記のようにすることで**静的ファイルをFirebase Hostingにホスティングすることができる**


```/package.json
{
  "name": "*****",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build && npm run build:copy:ssr",
    "build:copy:ssr": "rimraf functions/ssr && mkdirp functions/ssr && cp -R .nuxt/dist functions/ssr/dist && cp nuxt.config.js functions && cp -R functions/ssr/dist/client/ public && cp -R static/* public",
    "start": "nuxt start",
    "generate": "nuxt generate"
  },
}
```

#デプロイする
デプロイ前にローカルでテストしておく。
デフォルトならhttp://localhost:5000 で確認することができる。

```
firebase serve
```
```
✔  functions: Using node@10 from host.
i  functions: Watching "*****" for Cloud Functions...
i  hosting: Serving hosting files from: static
✔  hosting: Local server: http://localhost:5000
✔  functions[ssr]: http function initialized
```


問題がなさそうならデプロイする

```
firebase deploy
```

```
=== Deploying to '*****'...

i  functions: updating Node.js 10 function ssr(*****)...
✔  functions[ssr(*****)]: Successful update operation. 
i  hosting[*****]: finalizing version...
✔  hosting[*****]: version finalized
i  hosting[*****]: releasing new version...
✔  hosting[*****]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/*****/overview
Hosting URL: https://*****
```

``Hosting URL``に表示されているURLにアクセスして無事にデプロイできていれば完了

#参考
[SSRで作ったNuxtアプリをFirebase hostingで動的にデプロイする。](https://qiita.com/sychocola1/items/c3f329da3a14c85c3a73)
[【Nuxt.js】Nuxt.js SSRモードでfirebaseにデプロイする手順 2020年版](https://zenn.dev/sengosha/articles/de4c3bb6ffbe3be2b3c2)