Firebaseで複数のNuxt.jsプロジェクトをホスティングする2つの方法

Firebase でリソースを共有しつつ、 SPA を2つに分けたかったので調べました。


## 1. 「複数サイトのホスティング」を使用する

1. Firebaseコンソールにアクセス
1. 左のメニューから「Hosting」を選択
1. 一番下にある「詳細設定」の「別サイトを追加」をクリック
1. サイト名を入力し「サイトの追加」をクリック
    例として、デフォルトが `example-blog` 、追加したのが `example-app` とします。
1. すでに `firebase init` を実行済みであれば、生成済みの `firebase.json` を修正する

    ```firebase.json
    /*
     * フォルダ構成はこの様になっている前提
     * /開発rootフォルダ
     *   └/blog
     *      └/dist (ビルド先フォルダ)// https://example-blog.web.app でホスティング
     *   └/app
     *      └/dist (ビルド先フォルダ) // https://example-app.web.app でホスティング
     *   └/functions等 (あれば)
     *   └firebase.json
     */
    {
      // その他設定...
      "hosting": [{
        "target": "blog",
        "public": "blog/dist",
        // その他設定...
      },
      {
        "target": "app",
        "public": "app/dist",
        // その他設定...
      }]
      // その他設定...
    }
    ```

1. ビルドしてデプロイする
    1. `blog` `app` ともにビルド

    1. すべてのサイトにデプロイ

        ```
        firebase deploy --only hosting
        ```

    1. 指定したサイトだけにデプロイ

        ```
        // 例：blogだけデプロイ
        firebase deploy --only hosting:blog
        ```

### この方法の問題点
ドメインを同一にできなくなります。カスタムドメインを設定したとしても、どちらかはサブドメインを設定する必要が出てきます。（もしくは全く異なるドメイン）。

#### 参考
- [複数のサイトでプロジェクトのリソースを共有する | Firebase
](https://firebase.google.com/docs/hosting/multisites?hl=ja)

## 2. １つのサイトに複数のSPAをデプロイする

完成形イメージはこんな感じ。

```
/開発rootフォルダ
  └/blog  // ビルド先は public/blog 、
  └/app   // ビルド先は public/app にする
  └/functions等
  └/public
    └/blog // ここを https://hogehoge.web.app/blog で、
    └/app  // ここを https://hogehoge.web.app/app でホスティング
```

1. `firebase.json` を修正する

    ```firebase.json
    {
      "hosting": {
        "public": "public",
        "ignore": [
          "firebase.json",
          "**/.*",
          "**/node_modules/**"
        ],
        // rewritesルールを修正する
        "rewrites": [
          {
            "source": "blog/**",
            "destination": "/blog/index.html"
          },
          {
            "source": "app/**",
            "destination": "/app/index.html"
          }
        ]
      }
    }
    ```

1. Nuxt.js の `nuxt.config.js` を修正する

    `router.base` を指定しないと、デプロイ後に`/blog/.nuxt` ではなく `/.nuxt` にあるスクリプトを参照してしまうため、必ず指定します。

    1. blog の `nuxt.config.js`

        ```blog/nuxt.config.js
        export default {
          // 略
          router: {
            base: '/blog/',
          },
          // 略
          generate: {
            dir: '../public/blog',
          },
        }
        ```

    1. app の `nuxt.config.js`

        ```app/nuxt.config.js
        export default {
          // 略
          router: {
            base: '/app/',
          },
          // 略
          generate: {
            dir: '../public/app',
          },
        }
        ```

1. ルート `/index.html` にアクセスされた時の対応

    1. 既存の `index.html` を差し替える

    1. `firebase.json` を使ってリダイレクトする

        ```firebase.json
        "hosting": {
          // 略
          "redirects": [{
            "source": "/",
            "destination": "/blog",
            "type": 302,
          }]
          // 略
        }
        ```

1. ビルドしてデプロイ
    1. `blog` `app` ともにビルド
    1. デプロイ
        ```
        firebase deploy --only hosting
        ```
        個別のデプロイはできません。

### 2-2. 応用編

こんな感じにしたいですね。。

```
/開発rootフォルダ
  └/blog  // ビルド先は public 、
  └/app   // ビルド先は public/app にする
  └/functions等
  └/public // blog を https://hogehoge.web.app/ でホスティングしたい
    └/app  // app は https://hogehoge.web.app/app でホスティングしたい
```

1. `firebase.json` の `rewrites` `redirects` を修正

    ```
    "rewrites": [
      {
        "source": "/**",
        "destination": "/index.html"
      },
      {
        "source": "app/**",
        "destination": "/app/index.html"
      },
      "redirects": [{
        "source": "/",
        "destination": "/index.html",
        "type": 302,
      }]
    ]
    ```

1. `blog` の `nuxt.config.js` を修正

    `router` と `generate` を修正します

    ```blog/nuxt.config.js
    router: {
      // 何も指定しなくてOK
    },
    generate: {
      dir: '../public',
    },
    ```

1. あとはビルドしてデプロイ

### この方法の問題点
`blog` に `app` というフォルダやページは作成できなくなります（ビルド時に上書きされる、または上書きしてしまうため）。

#### 参考
- [Angularの複数プロジェクト構成とFirebeseホスティング - Qiita](https://qiita.com/kponda/items/6af48319b75ffc1bfeda)