webpackでfirebaseのconfigファイルをプロジェクト毎に動的に生成する（環境切り替えに使える）


firebaseをバックエンドにアプリ開発しててめんどくさいことの１つがconfigファイルをいちいち設定しないといけないということ。
環境の切り替えとかも想定するとなんとか簡素化できないかな・・・と思っていたところ、どうやら下記のような形で動的に取得できるらしいことが判明。

.firebasercが設定されている状態で、下記コードを実行すると、

```js
const firebaseTools = require('firebase-tools');

//関数定義
getConfig = async () => {
    const config = await firebaseTools.setup.web();
    console.log(config);
}

//実行
getConfig();
```

こんな感じでカレントのプロジェクトのconfig情報が取得できる。

```bash
{ projectId: 'staging-xxx',
  appId: '1:755101150039:web:629366d620ebbdcb24axxx',
  databaseURL: 'https://staging-xxx.firebaseio.com',
  storageBucket: 'staging-xxx.appspot.com',
  locationId: 'us-central',
  apiKey: 'AIzaSyChfPChI9bHe4Fo75tgB6CygZj2k4Mixxx',
  authDomain: 'staging-xxx.firebaseapp.com',
  messagingSenderId: '755101150xxx' }
```

ということは、config設定部分を上記コードに置き換えたら、いちいち環境設定を定義しなくてよい？と思ったのですが、その方法はうまくいきませんでした。その理由としては、

* firebaseTools.setup.web()は非同期メソッドである。
* 上記は、async/awaitすればいいだけかなと思うのですが、そもそもfirebase-toolsが私の環境ではうまく動作しなかった
  * http2が無い！とかのエラーが出て動かなかった（create-react-app環境）


なので、webpackで別途configファイルを生成しするようにした（で、それを読み込む）。
以下、そのメモ。

[この記事](https://medium.com/google-cloud-jp/webpack-multiproject-firebase-55d5bd8beb5d)が大変参考になったのですが、自分の環境に合わせて変えてみました。

また、今回は採用しませんでしたが、[このような方法](https://qiita.com/fullkawa/items/dee3754ba243970c37c7)もあるようです。

## 前提

* firebase-tools(CLI)がインストールされている
* 既にFirebaseのプロジェクトが存在している

## 準備

```bash
mkdir get-config
cd get-config
```

firebase initをかけてもいいのですが、いろいろファイルを作らないといけないので手動で設定します。
まず、必要な下記２つのファイルを生成しておきます。

```bash
touch firebase.json .firebaserc
```

そして、下記コマンドを実行してプロジェクトIDを調べておきます。

```bash
firebase list
```

そして今回生成したいプロジェクトIDをカレントのプロジェクトに設定します。

```bash
firebase use [project_id]
```

指定したプロジェクトのconfig情報を取得し、設定ファイルを生成してみます。

## ファイルを生成してみる

では、webpackを設定してconfigファイルを生成してみます。

### 各種作業用場所・ファイルの生成

直下にwebpack.config.jsを作成し、後の（作業）ファイルはちらかるのでfirebase-webpackってフォルダ以下に作ることにしました。

```bash
touch webpack.config.js
mkdir firebase-webpack
touch firebase-webpack/input.js #いちおうentryファイル
touch firebase-webpack/dummyConfig.json #loaderが使うダミーのjsonファイル
touch firebase-webpack/firebase-config-loader.js #ローダーを実装するファイル
```

なお、outputファイルはfirebaseConfig.jsとし、webpack.config.jsファイルと同階層に生成するようにしてみます。

>生成場所はwebpack.config.jsのoutputをお好みで変更してください。

### 必要なモジュールのインストール

CLIではなくライブラリとして利用するためにfirebase-toolsをローカルインストールします。

```bash
npm install --save-dev firebase-tools path
```

### input.js

inputとなるファイル。dummyConfig.jsを読み込みexportしてます。
Loaderで処理されconfig情報に置き換わります。

```js:input.js
export const firebaseConfig = require('./dummyConfig.json');
```

### dummyConfig.js

文字通りダミーなので{}だけ入れてます。

```json:dummyConfig.json
{}
```

>このファイルを直接importさせることもできるにはできます。。。

### firebase-config-loader.js

ローダーです。入力は無視して、非同期に取得したconfig情報を文字列化させたJSONで返しています。

```js:firebase-config-loader.js
const firebaseTools = require('firebase-tools');

module.exports = async () => {
    const config = await firebaseTools.setup.web();
    return `module.exports = ${JSON.stringify(config)}`;
}
```

### webpack.config.jsを設定する

各関連ファイルができたところでwebpack.config.jsを設定します。

```js:webpack.config.js
const path = require('path');

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, 'firebase-webpack', 'input.js'),
    output: {
        path: path.join(__dirname),
        filename: 'firebaseConfig.js',
        libraryTarget: 'commonjs2',
        library: 'Firebase',
    },
    module: {
        rules: [
            {
                test: /dummyConfig\.json$/,
                loader: './firebase-webpack/firebase-config-loader.js',
                type: 'javascript/auto'
            }
        ]
    }
}
```

### webpack実行

webpackコマンドを実行すればfirebaseConfig.jsが生成されるはずです。

```bash
webpack
```

## テストと応用

### 動作確認

プロジェクトを切り替えて生成ファイルが変更されるか確認してください。

```bash
firebase use [other_project_id]
webpack
```

反映内容は目視もできます（最後半あたりに目できるconfig情報があります。projectIdなどを確認するといいでしょう）。

### 応用

上記のことからfirebase use [project_id]を利用することでデプロイ先をコントロールすることができます。
package.jsonのscriptsに下記のように記述することで、デプロイ先を設定できます。

package.jsonファイルを生成。

```bash
npm init -f
```

scriptsを下記のように編集。
firebase hosting等を利用していれば自由にデプロイ可能です。

```json:package.json
"scripts": {
    "deploy-dev":"firebase use staging; webpack; firebase-deploy",
    "deploy-pro":"firebase use production; webpack; firebase-deploy; firebase use staging; webpack"
  },

```

下記コマンドでテスト用、本番用の切り分けが可能です。

```bash
npm run deploy-dev
npm run deploy-pro
```