作業ログ functionをリファクタ2019/08/31

※この記事に登場するソースコードは僕個人で開発しているプロジェクトのものです

更新が続くかわからないけど、作業ログ的な意味で残してみようと思います。

今回リファクタするfunction(一部省略)

uploadImages = async (images) => {
    if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
      var pusher = new Pusher('development-dummy-pusher-key', { // dev
        cluster: 'ap3',
        forceTLS: true,
        authEndpoint: '/api/v1/pusher/auth',
        auth: {
          headers: {
            'X-CSRF-Token': this.props.csrftoken,
          }
        }
      });
    } else {
      var pusher = new Pusher('production-dummy-pusher-key', { // prod
        cluster: 'ap3',
        forceTLS: true,
        authEndpoint: '/api/v1/pusher/auth',
        auth: {
          headers: {
            'X-CSRF-Token': this.props.csrftoken,
          }
        }
      });
    }
    const channel = pusher.subscribe('private-image-processing')

    for(let image of images){
      // 処理
    }
  }

このやっつけで書いたif文が明らかにいけてないので直します。

~~~~~~~~~~
ちなみにこのPusherってのはWebSocketのサーバを提供してくれているサービスです。development/productionなど複数の環境とそれら用のAPIを用意してくれていて、それぞれkeyやtokenなどが異なります。このfunctionはkeyを使いわけるためにenvで処理を分岐しています。我ながらひどいコードですね。
~~~~~~~~~~

Pusherについて詳しくはぐぐってくださいどうぞ

こういうやつはポリモーフィズムで置き換えるのが定石だと思うのでenvで定数を出しわける方法を調べてみたところ、webpackのDefinePluginを使うとよさそうだった。のでこれでいい感じにする

ちなみにこれを書いている2019/8/31時点ではJS雑魚マンです。このpluginの存在も今回初めて知りました。もしかしたらもっといい方法があるのかも?

webpack.js.org

まずwebpack.config.jsを書き換える

webpack.js.org

これを参考にwebpack.config.js内でmodeを取得

module.exports = (env, argv) => {
  const mode = argv.mode === 'production' ? 'production' : 'development'
  return [
    appConfig(mode),
  ]
}

appConfig

const PUSHER_KEYS = {
  'production': 'production-dummy-pusher-key',
  'development': 'development-dummy-pusher-key',
}

const appConfig = mode => {
  return Object.assign({}, config, { // ベースのconfigは別のとこで定義してます。めんどいので省略します
  plugins: [
    // これ追加
    new webpack.DefinePlugin({
      PusherKey: JSON.stringify(PUSHER_KEYS[mode]),
    }),
  ],
})

これで例のfunctionからPusherKeyでkeyを参照できるようになった。

あとはいわずもがな

uploadImages = async (images) => {
    const pusher = new Pusher(PusherKey, {
      cluster: 'ap3',
      forceTLS: true,
      authEndpoint: '/api/v1/pusher/auth',
      auth: {
        headers: {
          'X-CSRF-Token': this.props.csrftoken,
        }
      }
    });
    const channel = pusher.subscribe('private-image-processing')

    for(let image of images){
      // 処理
    }
  }

スッキリ!

そのうちこのchannelを別の場所で定義してimportして使うように書き換えます