飽き性の頭の中
Serverless Next.jsをFirebaseに置いたときのメモのサムネイル
IT技術メモ

Serverless Next.jsをFirebaseに置いたときのメモ

2019-03-21
# Firebase# Serverless# Next.js

Next.js の v8 からサーバーレス向けのビルドができるようになった。

Next.js のビルド自体はインストラクションとおりやればできるのだが、それをデプロイするときにちょっとハマったのでそれを簡単にメモしておく。

デプロイ先は使い慣れた Firebase を使った。

自分のサイトもこの方法で運用している。

Next.js でプロジェクトを作成

公式サイトを見ながらやればきっとできる。

Serverless Next.js

Firebase Functions のディレクトリにビルド

Firebase Functions のディレクトリ内に next のビルドが向くように設定をする。

next.config.js

const withTypescript = require("@zeit/next-typescript");
module.exports = {
  ...withTypescript(),
  distDir: "functions/build",
  target: "serverless",
};

こうすることで Firebase Functions からビルドした js が参照できるようになる。

Firebase Functions で返す

ビルドした JavaScript とエンドポイントをマッピング

ビルドした js を使って実際 Functions からビルドした js が実行されるようにマッピングする。

functions/index.js

const functions = require("Firebase-functions");
const indexPage = require("./build/serverless/pages/index");
// const messagePage = require("./build/serverless/pages/message");
const architecturePage = require("./build/serverless/pages/architecture");

exports.index = functions.https.onRequest((request, response) => {
  indexPage.render(request, response);
});

next 自体は TypeScript で書いているが、Firebase Functions はビルドされた next の JavaScript を見るだけなので、Firebase Functions は TypeScript ではなく JavaScript でやるのがお勧め。

ただrequireしてrenderするだけ。

Firebase のルーティング設定

エンドポイントの設定

Firebase はデフォルトで hosting にルーティングされるので、設定した Functions に redirect されるように記述する。

firebase.json

{
  "hosting": {
    "public": "public",
    "cleanUrls": true,
    "rewrites": [
      {
        "source": "/static/*",
        "destination": "/*"
      },
      {
        "source": "/",
        "function": "index"
      },
    ]
  },
  "functions": {
    "predeploy": ["yarn --prefix \"$RESOURCE_DIR\" build", "yarn export"],
    "source": "functions"
  }
}

画像などのアセットへのパス

画像は SSR では含まれず、クライアント側から再度リクエストが飛んでくる。それを返すパスの設定もする必要がある。

実際の URL はstatic/assets/images/avatar.jpgという感じになる。つまり、next.js では画像など静的ファイルは/static/次のファイルに入れる仕様なので、/static/*は hosting でいい感じに処理されるように/*にパスを書き換える。

Firebase hosting では/public/が配信される設定なので、ビルド時に

cp -r static public/

するといい感じに配信される。

バンドルされた JS のパス

SSR なので処理レンダーはサーバー側でなされるが、それ以降はクライアント側で JS を読み込んで実行される。

その JS をフェッチするリクエストは別途捌く必要がある。

URL を見てみると_next/static/hogehoge/pages/index.jsのようになっているので、public/_next/static/次にビルドされたファイルが入っていれば配信されるはず。

なので、

cp -r functions/build/static/* public/_next/static

もビルド時にする必要がある。

つまりどうするのか

ただビルドしたやつを Functions にマッピングするだけではなく、静的ファイルの配信もビルドしたものをいい感じに配置していかなければ動かないので意外とめんどくさい。

他にも賢い方法があるかもしれないが、とりあえず以下を実行すればすべてビルドしてデプロイまでされるようになっている。

yarn deploy

package.json はこんな感じになっている。

package.json

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "export": "rm -rf public && mkdir public public/_next public/_next/static && cp -r static public/ && cp -r functions/build/static/* public/_next/static",
    "deploy": "yarn build && Firebase deploy"
  }
}

yarn exportに前述したファイルのcp処理を書いている。ちょっとディレクトリ消したり作ったり移動したりしていてあまりきれいじゃないのでどうにかしたいとは思っている。

そして、Firebase のデプロイにフックして、事前に Functions のビルドとファイル移動が走るようになっている。

firebase.json

{
  "functions": {
    "predeploy": ["yarn --prefix \"$RESOURCE_DIR\" build", "yarn export"],
    "source": "functions"
  }
}

こうすることで汚いけれど、いい感じに Functions で捌きつつ静的ファイル配信ができるようになっているはず。

関連記事


タグ一覧

# 福岡:39# 東京:19# 移住:10# エナジードリンク:9# 大学院:9# Google:8# ブロックチェーン:8# Webエンジニア:7# Mac:6# Sony:6# Apple:5# Googleフォト:5# インドネシア:5# サントリー:5# 埼玉:5# AWS:4# Canon:4# EOS 8000D:4# Kindle:4# ZONe:4# 京都:4# 仮想通貨:4# 英語:4# 鴨川シーワールド:4# Docker:3# EOS8000D:3# Lightroom:3# Markdown:3# Pixel:3# React Native:3# iPad:3# iPad mini:3# アマルティア・セン:3# アメリカ:3# セブンイレブン:3# ラーメン:3# レッドブル:3# 卒業旅行:3# 紅葉:3# 長崎:3# API:2# ECR:2# ERC20:2# Expo.io:2# Firebase:2# Kindle Oasis:2# Kindle Paperwhite:2# LINE:2# MacBook Pro:2# NestJS:2# Next.js:2# Notion:2# Oculus:2# Oculus Quest:2# Pixel Buds:2# React:2# a7iii:2# iPhone:2# pandoc:2# re:Invent:2# zsh:2# かき小屋:2# カフェ:2# ギグワーカー:2# サーチコンソール:2# ジャカルタ:2# スターバックス:2# ステーキ:2# スマートウォッチ:2# ソラマチ:2# チョコレート:2# ニューヨーク:2# バリ島:2# パンとエスプレッソと:2# ヒュッゲ:2# ビーチ:2# ブックスタンド:2# マクドナルド:2# ミズマチ:2# モンスターエナジー:2# ワイヤレスイヤホン:2# 三千院:2# 両国:2# 兵庫:2# 千葉:2# 博多:2# 堀江貴文:2# 宮崎:2# 寿司:2# 嵐山:2# 川越:2# 広島:2# 新宿御苑:2# 日米学生会議:2# 有馬温泉:2# 東寺:2# 歴史:2# 江ノ島:2# 清澄白河:2# 独自ドメイン:2# 社会人:2# 神奈川:2# 神戸:2# 転職:2

©2022 tawachan All Rights Reserved.