揚げログ

Karaage(krgpi)の技術開発関連のブログです

Nuxt.jsで作ったSSRなwebサービスをfirebaseにデプロイする

環境

  • node v10.16.3
  • npm v6.9.0
  • nuxt v2.10.2

Nuxt.jsで作ったSSRなwebアプリをfirebase Hosting, functionsにデプロイするために行った設定の一覧です。すでにSSRモードでwebアプリができている前提で話を進めます。

1 firebase CLIの開発環境へのインストール

Firebase CLI リファレンス  |  Firebase

ここを参考に導入していきます。

2 プロジェクトの初期化を行う

$ firebase init

をプロジェクトルートで叩き、

  1. 自分のGoogleアカウントと紐付け
  2. 自分のFirebase プロジェクトと紐付け

を行います。それ以外の設定は、あとで変更するので、適当に進めます。

3 [プロジェクトルート]/firebase.json を編集する

プロジェクトルート直下に、 firebase.json というファイルが生成されているはずです。後ほど使うfirebase serve, firebase deploy のコマンドは、このファイルで設定を読み込んで実行されます。これを編集します。

{
  "functions": {
    "functions": {
      "source": "functions"
    }
  },
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssr"
      }
    ]
  }
}

functionsで、Firebase Functionsで動作するSSRの実行関数(js)部分の場所を指定しています。

hostingで、Firebase Hostingで静的配信するhtmlがある場所を指定しています。

rewritesで、静的ルートへのアクセスをSSRのルートへ飛ばします。sourceでどのページを飛ばすか、functionでどの関数に飛ばすかを指定しています。ここでは、"**"(全て)を"ssr"(あとで定義する関数)へ飛ばすことにしています。

4 [プロジェクトルート]/functions/package.jsonを編集する

プロジェクトルート直下に functionsというディレクトリが生成されいるはずです。firebase Functionsには、ここにあるファイル群がデプロイされます。

さらに、/functions/package.json も生成されていると思います。

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
+  "engines": {
+    "node": "10"
+  },
  "dependencies": {
    "firebase-admin": "^8.6.0",
    "firebase-functions": "^3.3.0",
 +   "nuxt": "^2.10.2"
  },
  "devDependencies": {
    "firebase-functions-test": "^0.1.6"
  },
  "private": true
}
  1. firebase Functionsで実行するnodeのバージョンを指定します。ここでは、 v10を指定します。ちなみに、Firebaseの制約で8か10しか指定できません(2019.11.25現在)
  2. また、firebase Functionsで実行する際に必要なNuxtを依存に追加します。
  3. 追加したあとで、npm install を実行してnuxtをインストールします。

5 [プロジェクトルート]/functions/index.jsを編集or作成する

functionsディレクトリの中に index.js というjsファイルを作成します。4で編集したpackage.jsonと同じ階層です。

このファイルは、Firebase Functionsで一番初めに実行されるファイルになります。3のrewritesで指定した"ssr"はここに作成する exports.ssr です。

const functions = require('firebase-functions');
const { Nuxt } = require('nuxt');
const nuxt = new Nuxt({
    buildDir: 'ssr',
    dev: false
});

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

buildDir で指定する 'ssr' は、[プロジェクトルート]/functions/ssr ですが、この次の5でこの場所に必要なファイルをコピーする設定をします。

6 [プロジェクトルート]/package.jsonを編集する

[プロジェクトルート]/package.json には、nuxtが使う依存関係や npm run dev でプレビューが起動するようなスクリプトが記載してあります。

{
  "name": "MyProject",
  "version": "1.0.0",
  "description": "My shining Nuxt.js project",
  "author": "krgpi",
  "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",
    "start": "nuxt start",
    "generate": "nuxt generate"
  },
  "dependencies": {
   ...(省略)
    "nuxt": "^2.10.2",
  },
  "devDependencies": {}
}

ここで、scripts→ build:copy:ssrを追加し、build で追加したbuild:copy:ssr も実行するように修正します。

build:copy:ssr に書いてあるコマンドで、nuxt buildで生成された出力ファイルを、先ほど3で指定したパスにコピーしています。

7 ローカルでプレビューする

プロジェクトルートで $ firebase serve を実行してみましょう。 $ firebase serve -p 3000 とかするとポート番号を指定することができます。

ここでは、3000にポート番号を指定したとします。コマンドを叩くと、以下のようなログが出てくると思います。

✔  functions: Using node@11 from host.
✔  functions: Emulator started at http://localhost:3001
i  functions: Watching "/[プロジェクトルート]/functions" for Cloud Functions...
i  hosting: Serving hosting files from: dist
✔  hosting: Local server: http://localhost:3000

8 Firebaseにデプロイする

ここまでできれば、プロジェクトルートで $ firebase deploy を叩くだけです。

参考

nuxt.js + firebase (cloud functions) で最小構成SSR | 丸ノ内テックブログ

SSR モードの Nuxt.js を Firebase に Deploy する Tutorial - Qiita

ローカルでテストしてサイトにデプロイする  |  Firebase

最後に

現状、firebaseのfunctionは、USリージョンしか使えなく日本からアクセスする場合、すごい遅い。東京リージョンがあるGCPのCloud Build→Cloud Runを使うのが良いと思います。