Ryan Johnson
4 min readFeb 12, 2017

Want to learn React? Check out my new course React for Beginners: Build and app, and learn the fundamentals.Want to learn React? Check out my new course React for Beginners: Build and app, and learn the fundamentals.

One webpack config to rule them all — environments that is

Webpack 2 is officially here — and to celebrate I wanted to share some tips on having one webpack config file to handle multiple environments.

There are plenty of examples out there demoing separate webpack.config files for each of your environments e.g. dev, production etc. Personally I prefer to avoid creating multiple files and handle everything in one config file, which I feel really helps simplify things.

Some PROS for single config file

  1. Much easier to decipher what’s happening in a build when you can look in a single file instead of piecing together many files.
  2. Avoiding duplication becomes much more straight forward
  3. Same config is used in all environments — no need to serve different files based on environment.

Ok, so enough of the benefits let’s get to how it’s done. For those who would just rather look at the full config file you can find it on my github.

Getting Started

The first thing we’re going to do is create a bare bones webpack.config.

You will notice that we export a function that returns our config object, and that function takes an env param. This env param will be passed in when you run webpack from the command line. To set the value for env you use webpack’s new --env.{ value } flag where value would be the environment you’re targeting.

// Assuming you're using npm scripts in package.json"scripts": {
"build:dev": "webpack --env.dev",
"build:prod": "webpack --env.prod -p"
}

Now that our config file has access to the env value passed from the command line we can conditionally add logic based on environment. To help with this I use a very helpful module created by Kent C. Dodds called webpack-config-utils.

NOTE: This is a partial webpack.config file created for this demo. To view my complete webpack.config visit my github.

The fist thing I do is setup two convenience methods ifProd, iNotProd using the getIfUtils from webpack-config-utils. These two methods can then be used to conditionally return something based on environment.

NOTE: The getIfUtils method provides more options than ifProd and ifNotProd. Have a look at the source to learn more.

// If env === prod then set cache = true, if not set cache = false cache: ifProd()// This would do the reverse of the above
cache: ifNotProd()

The other function we depend on is removeEmpty — when used in combination with ifProd and ifNotProd we gain a lot of flexibility in our config. Config properties like entry, modules.rules, and plugins usually take an array as their value, but if any items in the array are undefined that can cause issues. By wrapping an array in removeEmpty first all undefined items will be filtered out of the array.

plugins: removeEmpty([
new ProgressBarPlugin(),
ifProd(new webpack.LoaderOptionsPlugin({ minimize: true }))
])

By wrapping our plugins array in removeEmpty were are able to dynamically add plugins to our array based on environment. In the above example if env === 'prod' then the webpack.LoaderOptionsPlugin would be added, while the opposite would be true when not prod. This works because ifProd will return undefined when env !== 'prod’, and then removeEmpty would remove this item from the array.

Wrapping Up

Once you have an understanding of how the getIfUtils and removeEmpty methods work it’s just really rinse, lather, repeat to add this to other areas of your config file. I do realize this approach may not be for everyone, and that a single file approach could become unruly depending on the complexity of the build. When this becomes the case I still prefer leveraging comments, and whitespace to help organize things rather then busting things into separate files, but this really comes down to personal preference 😉.

Thanks again to Kent C. Dodds for creating these simple but powerful utility functions 💪💪.

For more React, Redux, and JavaScript reading follow me on Medium or Twitter.

Ryan Johnson

fullstack web developer • JavaScript • React.js • AngularJS • Node.js