Firebase Hosting にはリライトという機能があって、設定ファイル(firebase.json
)を書くことで例えば
- 全てのパスを
/index.html
へ向ける (SPA などで使う) /items/1234
へのリクエストを/items/id.html
へ向ける/api/get_item
へのリクエストを Cloud Functions のget_item
関数の HTTP トリガへ向ける
といったことが実現できます。
また cleanUrls 属性を使用することで URL から .html
拡張子を取り除くことができます。/page
へのアクセスは Hosting にアップロードされた /page.html
のファイルを取得するようになり、/page.html
へのアクセスは /page
へ 301 リダイレクトされるようになります。
これらの挙動はシュッとしたウェブアプリを作るためには大変便利でよく利用しますが、Firebase 本番環境へデプロイされたアプリケーションでしか効きません。本番環境では /items/1234
は /item/id.html
を返してくれるけど開発環境では /item/1234
は 404 になるといったつらみが生じます。
rewriteproxy#
そこで開発環境でもリライトと cleanUrls の挙動を再現してくれるプロキシを作りました。お手元の firebase.json
を読み込んで動作します。
リポジトリはこちら。
Go の標準ライブラリにある httputil.ReverseProxy
を使って書いたシンプルなリバースプロキシになっています。
使い方はこんな感じ。
$ rewriteproxy \
--port=3000 \
--firebase-json=/path/to/firebase.json \
--web-app-url=http://localhost:1234 \
--cloud-function-base-url=http://localhost:5001/your-project-id/us-central1
--web-app-url
はローカルで起動したウェブアプリの URL です。webpack-dev-server なら http://localhost:8080
だったり、parcel なら http://localhost:1234
だったりするでしょう。--cloud-function-base-url
はローカルで起動した Cloud Functions Emulator の URL を指定します。Firebase プロジェクトの初期状態で functions/
以下で yarn run serve
を叩くと立ち上がるやつです。
例#
パスの書き換え#
例えば
/items/1234
へのリクエストを/items/id.html
へ向ける
という設定を firebase.json
に書いた上で、上記コマンドでプロキシを起動しブラウザから http://localhost:3000/items/1234
へアクセスすると、ウェブアプリの http://localhost:1234/items/id.html
でホストされているファイルがブラウザに返るようになります。
Cloud Functions#
/api/get_item
へのリクエストを Cloud Functions のget_item
関数の HTTP トリガへ向ける
という設定を firebase.json
に書いた上で http://localhost:3000/api/get_item
へアクセスすると、ローカルの Cloud Functions エミュレータの http://localhost:5001/your-project-id/us-central1/get_item
が実行されます。
cleanUrls#
cleanUrls: true
にしていると .html
無しの URL を .html
付きにしてウェブアプリへプロキシしてくれます。
逆に .html
付きでアクセスすると .html
無しの URL へ 301 リダイレクトした上で先述のものと同じ挙動をします。
Root path#
また /
へのアクセスはウェブアプリの /index.html
へプロキシされます。
お手元の Firebase プロジェクトへの組み込み方#
プロジェクトのディレクトリには functions
, public
ディレクトリがあると思いますが同階層に dev
ディレクトリ(名前はなんでもいい)を用意して中で yarn add -D concurrently
だけしておきます。
PROJECT_ROOT
├── firebase.json
├── functions # Cloud Functions の実装
├── public # Hosting の実装
└── dev
├── package.json
├── setup
├── start
└── yarn.lock
start
スクリプトを用意して中身をこんな感じにします。URL やポート番号はお好みのものにしてください。自分はよく parcel dev サーバを 1235
で起動して rewriteproxy を 1234
で受けます。これで開発時には dev/start
を叩けばウェブアプリの dev サーバと Cloud Functions エミュレータと rewriteproxy が一緒に起動します。
#!/bin/sh -eux
cd "$(dirname "$0")"
./node_modules/.bin/concurrently --kill-others \
-n public,functions,proxy \
-c cyan,yellow,blue \
"cd ../public && yarn run dev" \
"cd ../functions && yarn run serve" \
"$(go env GOPATH)/bin/rewriteproxy --firebase-json=../firebase.json --port=1234 --web-app-url=http://localhost:1235 --cloud-function-base-url=http://localhost:5001/YOUR-FIREBASE-PROJECT-ID/us-central1"
ちなみに setup
はこんな感じにしておくと便利だと思います。
#!/bin/sh -eu
cd "$(dirname "$0")"
# dev
cd ../dev
yarn install
go get github.com/morishin/rewriteproxy
cd -
# public
cd ../public
yarn install
# functions
cd ../functions
yarn install
よければご利用ください#
Firebase Hosting のリライトや cleanUrls
を使ったウェブアプリを開発されている方には便利かと思うのでよかったらお使いください。
この rewriteproxy の実装はミニマムで、 Firebase Hosting のリライトに備わっている機能のうち自分がよく使う「パスの書き換え」「Cloud Functions へのプロキシ」「.html を消す」という機能しか実装されていません。その他の機能もローカルで使いたいという方は issue を立てたり実装して PR を出したりしていただければ幸いです。