webpackで本番ビルド時にfirebaseの環境変数を設定する

f:id:utr066:20190729161125j:plain

reactのアプリケーションを確認していたら、webpackの環境変数設定でおかしなことになっていたからメモ。

このアプリケーションはfirebaseで運用しているんだけど、firebaseで設定した環境変数をうまく取得できていなかった。やりたいこととしてはfirebase(本番環境)用にbuildする時にはfirebaseで設定した環境変数を参照してbuildできること。

webpackでの本番・開発別環境変数設定

webpackを使って本番環境・開発環境で参照する環境変数を分けたい場合、こんな書き方もすることはできるけど、これだと問題がある。仮にciとgithubを使ってデプロイする場合、.envファイルをgithubに置いておかないといけないだろう。

if (本番環境) {
  defineEnv = new webpack.DefinePlugin({
    'process.env': {
      API_KEY: JSON.stringify(functions.config().prod.api_key),
      AUTH_DOMAIN: JSON.stringify(functions.config().prod.auth_domain),
      DATABASE_URL: JSON.stringify(functions.config().prod.database_url),
      PROJECT_ID: JSON.stringify(functions.config().prod.project_id),
      STORAGE_BUCKET: JSON.stringify(functions.config().prod.storage_bucket),
      MESSAGING_SENDER_ID: JSON.stringify(functions.config().prod.messaging_sender_id),
    },
  });
} else {
  defineEnv = new webpack.DefinePlugin({
    'process.env': {
      API_KEY: JSON.stringify(process.env.DEV_API_KEY),
      AUTH_DOMAIN: JSON.stringify(process.env.DEV_AUTH_DOMAIN),
      DATABASE_URL: JSON.stringify(process.env.DEV_DATABASE_URL),
      PROJECT_ID: JSON.stringify(process.env.DEV_PROJECT_ID),
      STORAGE_BUCKET: JSON.stringify(process.env.DEV_STORAGE_BUCKET),
      MESSAGING_SENDER_ID: JSON.stringify(process.env.DEV_MESSAGING_SENDER_ID),
    },
  });
}

build→デプロイの順番だからねえ、buildするときにこのファイル参照されるんだからないとね・・・まあ普通にgithubにあげるのは嫌なので、別の方法を考える。

firebaseの環境変数をbuild時に参照したい。

firebaseに環境変数を設定しておいて、本番用のbuild時にその環境変数を参照したい。build時にwebpackの設定ファイルが参照されるわけだから、そのときに本番環境であるfirebaseの環境変数を参照できればその内容でbuildすることができる。そうすれば、環境変数ベタが気しなくていいしgithubにあげる必要もない。

firebaseで環境変数を設定する。

firebaseで環境変数を設定する方法は、以下の記事を参考にすればいいと思うよ。

qiita.com

build時にfirebaseの環境変数を参照する

やりたいのがまあwebpackでbuildしたときに本番環境の環境変数を参照して設定すること。

最初にfirebase-toolsを使えばできるのかなー・・・なんて試したけどちょっとダメみたい。

medium.com

$ yarn add firebase-tools

これでwebpackの設定ファイルに以下のような記述をすると設定した環境変数がターミナルに表示される。

const firebaseTools = require('firebase-tools')
firebaseTools.setup.web().then(config => {
    console.log(config)
})

ちょっとやったけどね。うまくいかんな。というかこれ非同期的な処理だから無理なんじゃないだろうか。公式的なツールtoolsとかfunctionsぐらいしか使えるのなさそうだし、以下の要件満たしたいときみんなどうしてるんだろう・・・

  • webpackでbuild時に本番環境の環境変数を参照したい
  • githubにenvファイルは上げない

firebase-setup-webを使う

taqmさんという方が作っていたこれを使ってみる。

github.com

qiita.com

記載されているREAD.meの通りに記載。

const config = require('firebase-setup-web');

const defParams = {
    'process.env.API_KEY': JSON.stringify(config.apiKey),
    'process.env.AUTH_DOMAIN': JSON.stringify(config.authDomain),
    'process.env.DATABASE_URL': JSON.stringify(config.databaseURL),
    'process.env.PROJECT_ID': JSON.stringify(config.projectId),
    'process.env.STORAGE_BUCKET': JSON.stringify(config.storageBucket),
    'process.env.MESSAGING_SENDER_ID': JSON.stringify(config.messagingSenderId),
}


// plugins内では設定した値を参照する。
    plugins: [
        new webpack.DefinePlugin(defParams)
    ],

これでbuildするとfirebaseに設定した環境変数を取ってきてくれた。

本番用と開発用にwebpackの設定ファイルを分ける

webpackの設定ファイル今までwebpack.config.js1つでやっていたけど、こういったことやっていくとごちゃごちゃになるから開発用と本番用に分けた方が使いやすそうですね。

qiita.com

buildしたい時にはwebpackの引数に--config 設定ファイルパスを与えてやればそのファイルを読み込んでくれる。

./node_modules/.bin/webpack --config webpack.prod.js

え、これFirebaseのプロジェクト運用どうしてるの?

なんか方法ないとおかしい気がするんだけど、これfirebaseでプロジェクト運用する時皆どうしてるの・・?なんかあるだろ・・・