NuxtアプリをFirebaseでホスティングするには

記事
IT・テクノロジー

NuxtアプリをFirebaseでホスティングするには

前回の投稿で紹介したように、NextやNuxtのようなサーバ側でレンダリング(描画)をするアプリの場合は、インターネットに公開するための設定方法が少し面倒になります。これは、通常のWebサーバーの機能である、リクエストされたURLの情報を提供する以外に、リクエストされた「ページを作る」という処理が必要になるためです。

この記事では、NuxtのアプリをFirebaseでホスティングするための設定方法の詳細を紹介します。

必要な手順

NuxtアプリをFirebaseで公開する手順です。前提条件として、公開したいNuxtのアプリはすでに開発済ということでその後の手順について紹介します。この例では、Nuxtのテンプレートのプロジェクトを公開するという形で紹介していきます。

1. Nuxtのアプリを作る
2. 公開用のフォルダを作成
3. Firebaseの設定
4. テスト
5. 公開(deployment)
Nuxtのアプリを作る
今回は、Nuxtのアプリの実際の実装は行いません。テンプレートのアプリをそのまま公開するという前提ですすめます。テンプレートのアプリは、「create-nuxt-app」を使って作成します。開発用のPCにインストールされていない場合は、まずこのパッケージをインストールします。

$ sudo npm install -g create-nuxt-app
$ npx create-nuxt-app nuxt-sample
(*)Windowsの場合「sudo」は必要ありません。

コマンドを実行すると、プロジェクトの設定について聞かれるので必要に応じて答えながらプロジェクトを作成してください。プロジェクトができたら、プロジェクトフォルダに移動して一応動作確認をしてください。

$ npm run dev
で開発用のサーバーが起動されて、「localhost:3000」でアクセスできます。

公開用のフォルダを作成
今回はNuxtのプロジェクトとは別に、Firebaseの公開用のプロジェクトフォルダを別に作成します。 オリジナルのNuxtの実装が壊れないように、別のフォルダーに必要な情報をコピーして公開する方法にしました。 念の為、Nuxtのアプリのフォルダはバックアップを作成される事をお勧めします。

$ mkdir deployment
$ cd deployment
$ mkdir nuxtsrc
フォルダを作成して、作成したフォルダに移動して、「nuxtsrc」というフォルダを作成します。

作成したフォルダにNuxtの実装をコピーします。コピーは2つのグループに分けます。

プロジェクトフォルダには、基本的に設定ファイルをコピーします

jsonfig.json
nuxt.config.js
package.json
tsconfig.json
nuxtsrcには基本的にフォルダをコピーします

asserts
components
layouts
middleware
pages
plugins
static
store
その上でファイルの設定パスが変わるので修正します。

nuxt.config.jsに以下の記述を追加します

export default {
    .....
    buildDir:"functions/.nuxt",
    srcDir:"nuxtsrc"
};
これで、Nuxtの公開用のイメージは、プロジェクトフォルダの下の「functions」フォルダに作成されるようになります。

Firebaseの設定
Firebaseの設定をします。プロジェクトのフォルダで必要なFirebaseのツールのインストールをします。

$ sudo npm install -g firebase-tools
$ npm install firebase-admin
$ firebase login
$ firebase init
(*)Windowsの場合、「sudo」は不要です。 インストールが完了したらFirebaseにログインします。ここでは、既にGoogleアカウントをお持ちという前提で書いています。Googleのアカウントをお持ちでない場合は作成してください。 その後で、プロジェクトフォルダの初期化をするために、「firebase init」を実行します。 必要な機能は:

* hosting
* functions

になるので、初期化の設定で選択してください。Firebaseのプロジェクトは予めFirebaseコンソールで作成しても良いですし、この初期設定で作成する事もできます。あとはfunctionsで使用する言語(JavascriptかTypescript)を選択します。ほとんどの設定はデフォルトの設定でOKです。

functions/index.js (typescriptを選択した場合は、functions/src/index.ts)を実装します。 これが、ページがリクエストされた際にサーバー側のNuxtアプリを起動するためのバックエンドの仕組みです。 Firebaseのfunctionsを利用して実装します。

import * as functions from "firebase-functions";
import * as express from "express";
const { Nuxt } = require("nuxt");
const app = express();
const config = {
  dev: false,
};
const nuxt = new Nuxt(config);
let isReady = false;
const readyPromise = nuxt
  .ready()
  .then(() => {
    isReady = true;
  })
  .catch(() => {
    process.exit(1);
  });
async function handleRequest(req, res) {
  if (!isReady) {
    await readyPromise;
  }
  res.set("Cache-Control", "public, max-age=1, s-maxage=1");
  await nuxt.render(req, res);
}
app.get("*", handleRequest);
app.use(handleRequest);
exports.nuxapp = functions.https.onRequest(app);
つづいて、Firebaseのfunctionsの設定を、プロジェクトフォルダに作成されたfirebase.jsonに追加します。 「hosting」の部分に「rewrite」の設定をします。これで、「public」フォルダにないURLがリクエストされた場合、上で実装したバックエンドのfunction「nuxtapp」を起動するようになります。

"hosting": {
    "public": "public",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "**",
        "function": "nuxtapp"
      }
    ]
  }
最後に、functions/package.jsonにプロジェクトフォルダにコピーしたNuxtアプリのpackage.jsonの「dependency」をコピーします。これは、FirebaseのバックエンドでNuxtのモジュールを呼び出しますが、この部分には必要なモジュールがインストールされていないのでエラーになってしまいます。そこで、Nuxtで使っているパッケージを全て、functions/package.jsonにコピーします。 その上で、functionsフォルダに移動して必要なパッケージをインストールします。

$ npm install
これで、プロジェクトフォルダでNuxtのプロダクションイメージをビルドします。

$ npm run generate
その後でスタティックファイルを「public」フォルダにコピーします

* 「functions/.nuxt/dist/_nuxt」を「public/_nuxt」にコピー
* 「src/static」の中身を「public」にコピー
毎回コピーするのは面倒なのでスクリプトを書いて置くと便利です。

テスト
これで、公開の準備はできましたが、公開する前のFirebaseのエミュレーターを使ってテストします。

$ firebase serve
を実行すると標準設定ならば「localhost:5000」でNuxtのアプリにアクセスできるはずですので確認してください。

公開(deployment)
あとは、公開するだけです

$ firebase deploy
これで、インターネットに公開されます。シンプルなサイトや、フロントエンドのフレームワークのReactやVueに比べるとちょっと面倒ですが慣れればそれほど大変ではありません。

Firebaseのプラン
手続きの方は以上ですが、NuxtアプリをFirebaseで公開するにあたって何点か注意点があるのでまとめておきます。

1つ目は、Firebaseの料金プランを無料プラン(Spark Plan)から従量制プラン(Blaze Plan)に変更する必要があります。この変更をしても、利用の範囲が無料の範囲ならば料金は発生しません。

2つ目は、実はFirebaseのFunctionを使うと完全に無料ではなくなります。これは、Functionsで使用する一部のストレージが無料でないのと、インターネットに公開する際のデプロイメントのプロセスで料金が発生する場合があるからです。いずれにしても、ここで発生する料金はよほど大規模なあぷりでない限り、月額で数セント(数円)程度です。

ローカルのテスト環境での使用の場合は、無料プランでも利用できます。

サーバーサイドのレンダリングは必要か?
前回の記事でも少し触れていますが、サーバーサイドのレンダリング(描画)が必要かどうかはある程度検討した方が良いと思います。

紹介したように、サーバーサイドのホスティングはサービスが限定される場合が多く、Firebaseはサポートしていますが公開するための設定はちょっと面倒ですし、少額とはいえ料金が発生します。 ブログの運営で、サーバーサイドとフロントエンドのレンダリングの実装を両方作成して試してみましたが、大きな違いはありませんでした。 有料コンテンツを配布しているので、決済の実装にバックエンドが必要なため、サーバーサイドのレンダリングを採用た事以外は現時点では大きな違いは感じていません。

Nextのデプロイメントは?
Nextもサーバーサイドのフレームワークでよく利用されていますが、基本的なコンセプトはNuxtと同じです。 Firebaseのバックエンドをfunctionsを利用して、Nextのアプリを呼び出す形で公開できます。 フォルダの構成や設定の変更部分が若干違いますが基本的な設定は同じです。

「sv-sw.com」 のWebサイトは、Nextで実装されており、ホスティングはFirebaseを利用して公開しています。

ブログは、Markdownで記述して、Firebaseのストレージにポストしています。ページのリクエストがあると、MarkdownをHTMLに変換してページを表示するような仕組みになっています。実装は、Nextのチュートリアルを参考に作成しています。

まとめ
NuxtのアプリもFireaseのホスティングで公開する事ができます。 設定には、Firebaseのfunctionsの機能を利用する必要があるので、通常のホスティングよりは少し面倒です。

Firebaseのホスティングは基本的に、HTML/CSS/Javascript(Node.js)系の実装ならば対応可能です。通常はReactやVueのフレームワークで十分に対応可能ですが、NextやNuxtも必要に応じて利用ができます。

開発するアプリの要求仕様に合わせて選択できるのは便利です!

サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す