Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

webpack.config.jsのなかでビルド環境を調べる方法

More than 1 year has passed since last update.

この記事について ✍️

あるプロジェクトでビルドツールとして webpack を利用していて、
そのプロジェクトで外部ツールを使って利用率を計測をしようとしました。

その外部ツールは本番用と開発用でAPIKeyが違いまして、
webpackの設定ファイルでビルド環境ごとに変数を出し分ける方法を調べるのにすこし手間取りまして。。

この記事の後半では 「webpackでビルド環境を調べ、環境変数を宣言する方法」 をサクッとご紹介するので時間がない方はそちらを!

前半部分では、なぜビルド環境をwebpackで調べたかったのか説明します。

環境 🤖

この記事では webpack v4.27.1webpack-cli v3.1.2 を使っています

前半: なぜビルド環境をwebpackで調べたかったのか

外部の分析ツール(Google Analytics的な)を使いたかったのですが、
本番環境と開発環境で分析を分けたかったんですよね。

その分析ツールをつかうにはAPIKeyが必要でして、
本番環境と開発環境で分析結果を分けるには、環境ごとにKeyを持っておく必要がありました。

ということは、例えばこんなイメージのコードができあがりそうです。

index.js
import {logging} from "some_external_service"

if (environment === "production") {
  logging("本番用APIKey")
}
else if (environment === "development") {
  logging("開発用APIKey")
}

まず2点微妙な点があります

  1. ビルドされた環境とは関係ない方のAPIKeyもソースコードに書いておく必要がある
  2. APIKeyが変わったときにわざわざソースコードを修正する必要がある

1 に関しては、ビルド環境ごとにAPIKeyを選べれば、関係ないAPIKeyをソースコードに存在させる必要がなくなります。
2 に関しては、変数としてどこかに置いておけば、APIKeyがいつか変わってもソースコードは修正せずにすみます。

となると

1. webpackでビルドするときに必要な方のAPIKeyだけを持っておいて、
2. それをソースコードから呼べるよう環境変数に持っておく

しかないんですよね。(もっといい方法あったら教えてください!🙇‍♂️)

ということは、設定ファイルである webpack.config.js のなかで上記 12 をやる必要が出てきます。
(コマンドラインで読み込む設定ファイルを指定する方法もありますが、今回はその方法には触れません)

後半部分では、どうやれば実現できるか紹介します!

後半: webpackでビルド環境を調べ、環境変数を宣言する方法

1. webpack.config.jsのなかでビルド環境を調べる方法

そもそも、ビルド環境を調べる前に環境を指定する必要がありますね。

1. ビルド環境を指定する

2つ方法があります

1. modeを設定する方法

webpack.config.jsに直接書き込む方法があります。

webpack.config.js
module.exports = {
  mode: 'production'
};

ただ今回は 1つの設定ファイル でやりたいので、上のやり方よりもwebpackCLIを使ってmodeフラグを渡す方法が向いてます。

package.json
  "scripts": {
    "build_prod": "webpack --mode=production",
    "build_dev": "webpack --mode=development"
  },

modeは、 productiondevelopment の二つの選択肢があります。

modeを使うメリットは、webpackによって勝手にビルドが最適化される点です。productionだとminifyとかしてくれます。

一方、modeより指定方法が豊富というか、そもそも趣旨がちょっと違う指定方法があります。それが、 envフラグです。

2. envを指定する方法

こちらは設定ファイルで指定する方法はなく、webpackCLIを使ってenvフラグを渡します。

package.json
  "scripts": {
    "build_prod": "webpack --env.production --environment=honban",
    "build_dev": "webpack --env.development "
  },

変数を宣言する感じですが、シンタックスシュガー的な書き方ができて、

例えば上の --env.production は、 webpack.config.js で受け取るときには
productionの中身は true というbooleanになります。

上の --env.development の中身は "develop" という文字列になります。

文字列を直接指定することもできて、 --environment=honban のenvironmentの中身は "honban" という文字列になります。

指定方法はたくさんありますが、詳しくは こちら に書いてあります!

さてここまでは環境を指定する方法を書きましたが、次はビルド環境を調べる方法をご紹介します!

2. ビルド環境を調べる

modeフラグenvフラグ でビルド環境を指定しましたが、それぞれ受け取り方が違います。

modeもenvも一気にご紹介します。

package.json
  "scripts": {
    "build_prod": "webpack --env.production --environment=honban --mode=production",
  },
webpack.config.js
// 第一引数にはenvフラグで指定した変数が入ってくる
// 第二引数には指定したmodeとか色々入ってくるが、今回はmodeだけ取り出す
module.exports = (env, {mode}) => ({ 
  console.log(env.production)  // true
  console.log(env.environment) // "honban"
  console.log(mode)            // "production"
  ...
});

このような感じで、 module.exports にオブジェクト自体ではなく オブジェクトを返す関数 を渡します。
webpack内部では、この関数に引数を与えて実行するようになっているんですね。

さて、 webpack.config.js のなかでビルド環境が調べられたところで、
最後に環境変数を宣言する方法をご紹介します。

2. webpack.config.jsのなかで環境変数を宣言する方法

webpackが提供する DefinePlugin を利用します

webpack.config.js
module.exports = (env, {mode}) => ({ 
  plugins: [
    new webpack.DefinePlugin({
      API_KEY:
        env.environment === "honban"
          ? JSON.stringify("本番用APIKey")
          : JSON.stringify("開発用APIKey")
    })
  ]
  ...
});
index.js
import {logging} from "some_external_service"

logging(API_KEY)

最後に

今回は webpackでビルド環境を調べ、環境変数を宣言する方法 をご紹介しました。

たくさんのビルド環境を使い分けなければならないプロダクトで、
さらに設定ファイルを環境の数だけ用意したくないという場合にとても有効な方法だと思います。

もっとスマートなやり方があったら教えてください、それでは良いお年を!

fringe81
Fringeは、最新のテクノロジーとプロフェッショナルによるサービスにより、社会課題に仮説を立てて市場に広げていくことで、数十年という長期的なスパンで価値を生み出し続け、より良い世界を創る集団です。 既存の領域に限らず、時流を読み、仮説を生み出し、テクノロジーの力で優れたサービスを生み出し続けます。
https://www.fringe81.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away