Vue CLIでFirebase SDKとFirebaseUIを外部から読み込みたい!


Firebase SDKはデカい!

Web用のFirebase SDKは、npmモジュール、CDN、Hosting URLからの3つの方法で導入できます。
https://firebase.google.com/docs/web/setup#add-sdks-initialize

しかし、npmモジュールをwebpackでバンドルすると、ビルドされたファイルの大半をFirebase SDKが占める、なんてこともあります。

加えて、FirebaseUIの日本語版のnpmモジュールは1.0.0で止まっちゃってるので最新版を使いたいときはCDNを使うしかなさそうです。

そこでCDNから読み込みたいのですが、Vue CLIを使ってビルドする際、CDNとwebpackを共存させる方法で詰まったので記録しておきます。

webpackに外部ファイルの存在を告げる

webpackに「外部ファイルを使うからビルドファイルにはこのモジュールはいらないよ」と教える必要があります。

そのためにはwebpack.config.jsexternalsというプロパティを追加します。
https://webpack.js.org/configuration/externals/

Vue CLIの場合、vue.config.jsに追加できます。
https://cli.vuejs.org/guide/webpack.html#simple-configuration

vue.config.js
module.exports = {
    configureWebpack: {
        externals: {
            firebase: 'firebase',
            firebaseui: 'firebaseui'
        }
    }
}

index.htmlにリンクを追加する

npmモジュールの場合、

main.js
import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/auth'

このように必要な機能を部分的にimportしますが、CDNの場合、

public/index.html
<head>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>タイトル</title>

    <script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-firestore.js"></script>

    <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth__ja.js"></script>
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
</head>

index.htmlに必要なSDKのCDNリンクを追加して、

main.js
import firebase from 'firebase'

このようにimportすれば、必要な機能だけ導入できます。

Hosting URLを使いたい!

これでCDNからの読み込みは出来るはずですが、Firebase Hostingを使っている場合、予約済みURLから読み込んだ方がパフォーマンスが向上するようです。
https://firebase.google.com/docs/hosting/reserved-urls

これもCDNと同様にindex.htmlに追加すれば使えます。

public/index.html
<head>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>タイトル</title>

    <script src="/__/firebase/7.8.0/firebase-app.js"></script>
    <script src="/__/firebase/7.8.0/firebase-auth.js"></script>
    <script src="/__/firebase/7.8.0/firebase-firestore.js"></script>
    <script src="/__/firebase/init.js"></script>

    <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth__ja.js"></script>
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
</head>

/__/firebase/init.jsを追加すれば、初期化処理をコピペする必要はありません。

ローカルサーバーでも使いたい!

npm run serveで立ち上げたローカルサーバーでは/__/firebase/にアクセスしても「そんなもん無いよ?」と言われてしまいます。
npm run build + firebase serveではfirebase-toolsが/__/firebase/にアクセスできるようにしてくれるのですが、ファイルを変更するたびにビルドしていたら開発効率が落ちてしまうでしょう。

解決するのは簡単で、/__/firebase/の頭にFirebase HositingのURLを付けるだけです。

public/index.html
<head>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>タイトル</title>

    <script src="https://~.firebaseapp.com/__/firebase/7.8.0/firebase-app.js"></script>
    <script src="https://~.firebaseapp.com/__/firebase/7.8.0/firebase-auth.js"></script>
    <script src="https://~.firebaseapp.com/__/firebase/7.8.0/firebase-firestore.js"></script>
    <script src="https://~.firebaseapp.com/__/firebase/init.js"></script>

    <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth__ja.js"></script>
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
</head>

絶対パスでは速度が落ちるらしいので環境変数を使って開発環境だけで使うといいと思います。

.env
VUE_APP_FIREBASE_URL=
.env.development
VUE_APP_FIREBASE_URL=https://~.firebaseapp.com
public/index.html
<head>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>タイトル</title>

    <script src="<%= VUE_APP_FIREBASE_URL %>/__/firebase/7.8.0/firebase-app.js"></script>
    <script src="<%= VUE_APP_FIREBASE_URL %>/__/firebase/7.8.0/firebase-auth.js"></script>
    <script src="<%= VUE_APP_FIREBASE_URL %>/__/firebase/7.8.0/firebase-firestore.js"></script>
    <script src="<%= VUE_APP_FIREBASE_URL %>/__/firebase/init.js"></script>

    <script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth__ja.js"></script>
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
</head>

環境変数については以下を参照
https://cli.vuejs.org/guide/mode-and-env.html