Vite + React + TypeScriptで作成したWebアプリを、Firebase Hostingへデプロイしました。
基本的にはFirebase CLIから初期化してデプロイするだけなのですが、途中で
-
ImportMeta.env関連のTypeScriptエラー - GitHubリポジトリをCloud Shellへクローンする際の認証
- Cloud ShellからGitHub連携を設定しようとしてOAuth認証に失敗
など、いくつかハマったポイントがありました。
今後またFirebase Hostingを使うときのために、実際に行った手順と対処方法をまとめておきます。
環境・前提
今回使用した主な環境は以下です。
- Vite
- React
- TypeScript
- Firebase Hosting
- GitHub
- Google Cloud Shell
すでにVite + React + TypeScriptでWebアプリを作成しており、GitHubリポジトリで管理している状態からFirebase Hostingへデプロイしました。
1. Firebase側の準備
まずFirebase Consoleからプロジェクトを作成します。
- Firebase Consoleを開く
- プロジェクトを作成、または既存プロジェクトを選択
- プロジェクト概要から「ウェブアプリを追加」(
</>)を選択 - アプリのニックネームを入力
- 「このアプリの Firebase Hosting も設定します」にチェックを入れて登録
登録するとFirebase SDKの設定に必要な情報を確認できます。
2. アプリ側でFirebaseを利用できるようにする
firebaseパッケージをインストール
まず、プロジェクトにFirebaseのパッケージを追加します。
npm install firebase
これでTypeScriptから次のようにFirebase SDKをimportできるようになります。
import { initializeApp } from "firebase/app";
.env.local にFirebaseの設定値を記述する
Firebaseの設定値は、プロジェクトルート直下の .env.local に記述しました。
Viteから環境変数を参照する場合、変数名には VITE_ プレフィックスが必要です。
VITE_FIREBASE_API_KEY=your_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project_id.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id
実際の値はFirebase Consoleに表示される設定値に置き換えます。
また、.env.local に実際の設定値を記載する場合は、GitHubへ誤ってコミットしないよう .gitignore の設定も確認しておきます。
src/firebase.ts を作成する
Firebaseを初期化するため、src/firebase.ts を作成しました。
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
};
export const app = initializeApp(firebaseConfig);
import.meta.env を使うことで、先ほど .env.local に設定した VITE_ から始まる環境変数を読み込めます。
3. ImportMeta.env の型エラーにハマった
ここでTypeScriptのチェックを実行したところ、以下のエラーが発生しました。
Property 'env' does not exist on type 'ImportMeta'
import.meta.env を使用しているものの、TypeScript側でViteが提供する型定義を認識できていないことが原因でした。
src/vite-env.d.ts を作成
src/ 直下に vite-env.d.ts を作成し、以下を記述しました。
/// <reference types="vite/client" />
これでViteが提供する ImportMetaEnv などの型定義が読み込まれ、import.meta.env をTypeScript側で認識できるようになりました。
ローカルでは動いていても、CIなどでTypeScriptのチェックを実行した際にこのエラーが出る場合があるため、vite-env.d.ts が存在しているか確認するとよさそうです。
4. Cloud ShellからGitHubリポジトリを取得する
今回はCloud ShellからFirebase Hostingの設定を行いました。
GitHubリポジトリをCloud Shellへクローンするため、GitHub CLI(gh)を使用しました。
まずGitHubへログインします。
gh auth login
表示されるURLとコードを使用して、ブラウザからGitHub認証を行います。
認証できたらリポジトリをクローンします。
gh repo clone <username>/<repository-name>
cd <repository-name>
続いて依存関係をインストールします。
npm install
GitHubではGit操作におけるパスワード認証が廃止されているため、HTTPS経由で単純にユーザー名・パスワードを入力する方法では認証できません。
Cloud Shellから作業する場合、gh auth login を使うとブラウザ経由で認証できました。
5. Firebase Hostingを初期化する
リポジトリへ移動した状態で、Firebase Hostingの初期化を行います。
firebase init hosting
いくつか質問されるので、今回は以下のように設定しました。
| 質問 | 選択した内容 |
|---|---|
Please select an option |
Use an existing project |
Select a default Firebase project |
対象のprojectId |
What do you want to use as your public directory? |
dist |
Configure as a single-page app (rewrite all urls to /index.html)? |
Yes |
Set up automatic builds and deploys with GitHub? |
No |
なぜpublic directoryをdistにするのか
Viteでは、npm run build を実行するとデフォルトでビルド結果が dist ディレクトリへ出力されます。
Firebase Hostingには、このビルド済みファイルを公開してもらうため、public directoryとして dist を指定します。
6. Cloud ShellでGitHub自動デプロイを設定しようとしてハマった
今回一番ハマったのがここでした。
firebase init hosting の途中で、
Set up automatic builds and deploys with GitHub?
と聞かれます。
最初はGitHubと連携できるなら便利そうだと思い、Yes を選択しました。
ところがCloud Shell上からGitHubのOAuth認証を行おうとすると、ブラウザ認証後に以下のlocalhostへリダイレクトされました。
localhost:9005
その結果、
ERR_CONNECTION_REFUSED
となり、認証を完了できませんでした。
Cloud Shell上でFirebase CLIを実行している一方、OAuth認証に使用しているブラウザは手元のPCで動作しています。そのため、認証後に localhost:9005 へリダイレクトされても、ブラウザから見た localhost はCloud Shellではなく手元のPCを指してしまいます。
今回はGitHub Actionsによる自動デプロイが必須ではなかったため、firebase init hosting をやり直し、
Set up automatic builds and deploys with GitHub?
では No を選択しました。
これでGitHub連携を行わず、Firebase Hostingの初期化を進めることができました。
GitHub Actionsとの連携は後から設定できる
今回の作業では実施していませんが、Firebase Hostingの初期化後でも、以下のコマンドでGitHub Actionsとの連携を追加できます。
firebase init hosting:github
Cloud Shellではなく、GitHubリポジトリを手元のPCへクローンし、ローカル環境からこのコマンドを実行すれば、ブラウザとFirebase CLIが同じPC上で動作するため、今回のような localhost:9005 の問題を回避できます。
そのため、Cloud ShellからFirebase Hostingを初期化する場合は、無理にGitHub連携まで同時に行わず、
Cloud Shell
↓
firebase init hosting
↓
GitHub連携は No
↓
Firebase Hostingへデプロイ
必要になったら後から
↓
ローカルPCへリポジトリをclone
↓
firebase init hosting:github
という形で分けて設定する方法もあります。
今回は手動で firebase deploy する方法で問題なかったため、GitHub Actionsとの連携は行わず、そのままデプロイへ進みました。
7. ビルドしてFirebase Hostingへデプロイ
Firebase Hostingの設定が完了したら、アプリをビルドします。
npm run build
ビルドに成功すると dist ディレクトリが生成されます。
続いてFirebase Hostingへデプロイします。
firebase deploy
正常に完了すると、ターミナルに以下のようにHosting URLが表示されます。
Hosting URL: https://xxxxxxxx.web.app
実際にURLへアクセスし、作成したWebアプリが表示されることを確認しました。
ハマったポイントまとめ
| エラー・事象 | 原因 | 対応 |
|---|---|---|
Cannot find module 'firebase/app' |
firebase が依存関係に入っていない |
npm install firebase を実行 |
Property 'env' does not exist on type 'ImportMeta' |
Viteの型定義をTypeScriptが認識できていない |
src/vite-env.d.ts に /// <reference types="vite/client" /> を記述 |
| GitHubの認証に失敗する | GitHubのパスワード認証を使用しようとした |
gh auth login でブラウザ認証 |
localhost:9005 で接続拒否 |
Cloud ShellからGitHub OAuth認証を実行した際のリダイレクト | Hosting初期化時のGitHub自動設定を No にした |
まとめ
Vite + React + TypeScriptで作成したWebアプリをFirebase Hostingへデプロイしました。
基本的には、
Firebaseプロジェクト作成
↓
アプリ側にFirebase設定を追加
↓
firebase init hosting
↓
npm run build
↓
firebase deploy
という流れで公開できます。
今回は特に、
-
import.meta.envを使うためのViteの型定義 - Cloud ShellからGitHubへ接続するときの認証方法
- Cloud Shell上でFirebase HostingとGitHubを連携しようとした際のOAuthエラー
で少しハマりました。
Firebase Hostingへのデプロイ自体はかなり簡単ですが、Cloud ShellやGitHubを組み合わせると認証周りで詰まることがあったので、同じところで困ったときに見返せるよう残しておきます。