Nuxt.jsをSSRモードでFirebaseにデプロイする
はじめに
n番煎じだって感じだけど、メモ書き程度に置いておきます。
使うもの
Nuxt.js
Firebase
今回使うのは以下のもの
- Firebase Hosting
- 静的ファイルのホスティングサービス
- Cloud Functions for Firebase
- Node.jsを動かせるFaaS
やり方
やるだけ
Nuxtプロジェクトを作る
create-nuxt-appを使います。
$ npx create-nuxt-app ssr-test-app create-nuxt-app v2.15.0 ✨ Generating Nuxt.js project in ssr-test-app ? Project name ssr-test-app ? Project description My fantabulous Nuxt.js project ? Author name mnao305 ? Choose programming language JavaScript ? Choose the package manager Npm ? Choose UI framework None ? Choose custom server framework None (Recommended) ? Choose Nuxt.js modules Progressive Web App (PWA) Support ? Choose linting tools ESLint ? Choose test framework None ? Choose rendering mode Universal (SSR) ? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
色々と質問されるけどお好みで。
今回は面倒なのでTSは無しで、UI, Serverフレームワークも入れてません。
プロジェクト作成が終わったら一度ローカルで動かしてみる。
Nuxtプロジェクトの一部修正
分かりやすくするためにクライアント向けのディレクトリをまとめます。
nuxt.config.jsに以下を追加。
srcDir: 'client/',
プロジェクトルートにclient
というディレクトリを作り、今Nuxtプロジェクト上に存在する全てのディレクトリを移動する。
client ├── assets ├── components ├── layouts ├── middleware ├── pages ├── plugins ├── static └── store
Firebaseプロジェクトを作る
やるだけ
Nuxtプロジェクト上でFirebaseのセットアップ
いつも通りCLIでセットアップ
$ firebase init ? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. ◯ 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 ◯ Emulators: Set up local emulators for Firebase features ? Please select an option: (Use arrow keys) ❯ Use an existing project Create a new project Add Firebase to an existing Google Cloud Platform project Don't set up a default project ? Select a default Firebase project for this directory:↑で作ったプロジェクト ? What language would you like to use to write Cloud Functions? JavaScript ? Do you want to use ESLint to catch probable bugs and enforce style? No ? Do you want to install dependencies with npm now? Yes ? What do you want to use as your public directory? public ? Configure as a single-page app (rewrite all urls to /index.html)? No
後で変えられるし適当に。
Cloud Functions側のコード諸々を書く
node10を使うようにする
以下のように修正
"engines": { - "node": "8" + "node": "10" },
Cloud Functionsでnode10を使う場合、Blaze(従量課金)プランにしないといけないので注意。
node8も今後サポート終わるので、Functions使うならプラン上げるの必須になるぽい。
クライアント側の依存パッケージをFunctions側にも入れる
プロジェクトルートのpackage.json
にあるdependencies
内ののパッケージをfunctions側のpackage.jsonに移植します。コピペでOK。
コピペしたらnpm i
でインストールしておく。
新しくパッケージを入れたら同じようにコピペしておく。
index.jsの修正
functions/index.js
を編集します。
const functions = require('firebase-functions') const { Nuxt } = require('nuxt') const nuxt = new Nuxt({ buildDir: '.nuxt', dev: false }) exports.ssr = functions.https.onRequest(async (req, res) => { await nuxt.ready() return nuxt.render(req, res) })
ちなみにfunctions.region('asia-northeast1').https.onRequest(...
みたいな感じに指定すれば東京リージョンが使用できるが、このような動的コンテンツを配信するためにはus-central1
リージョンじゃないとダメらしい。(一敗)
公式にも書いてある。
重要: HTTP 関数を使用して Firebase Hosting で動的コンテンツを提供するには、us-central1 を使用する必要があります。
そう考えると読み込み速度的な意味だと微妙な気がする。教えて偉い人。
デブロイ用ビルドコマンド設定
npm scriptとして下記を追加。
"build:firebase": "npm run clean && npm run build && npm run copy", "clean": "rm -rf public && rm -rf .nuxt", "copy": "mkdir public && cp -R functions public/server && cp -R client/static public/client && cp -R .nuxt public/server && cp -R public/server/.nuxt/dist/client public/client/assets
Firebase設定ファイルの修正
firebase.json
を以下のように修正。
{ "functions": { "source": "public/server" }, "hosting": { "public": "public/client", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [{ "source": "**", "function": "ssr" }] } }
やってる事としてはこんな感じ
ビルド&デプロイ
$ npm run build:firebase $ firebase deploy
以上。
最終形態のリポジトリ github.com