Passing Environment Variables Into Your Code With Webpack

How To Configure Dev/Prod Firebase Databases Using Webpack’s DefinePlugin

Justin Tulk
Apr 22, 2017 · 1 min read

I’m currently working on an application using Firebase for the backend. I just set up a second Firebase database to be my staging environment, and want to configure Webpack so that Production and Development compiles use the staging and production Firebase URLs appropriately.

Currently, I’ve got dev and prod builds of Webpack running with the following config:

// package.json
"scripts": {
"start": "webpack-dev-server --env.dev --open --watch --progress --colors"
}
// webpack.config.js
function buildConfig(env) {
return require("./config/webpack." + Object.keys(env)[0] + ".js")(env);
}
module.exports = buildConfig;
// webpack.dev.js
module.exports = function(env) {
return {
// webpack configuration object
}
}

My npm start script runs webpack-dev-server and configures the env object. The config then reads that object, and returns my development config. Voila. It’s the pattern detailed in the docs.

The next step is passing in the appropriate Firebase URL based on which configuration is used. The way to do this is to use Webpack’s DefinePlugin functionality to specify values at compile-time.

// webpack.dev.config
new webpack.DefinePlugin({
"FIREBASE_URL": JSON.stringify("https://myapp-staging.firebaseio.com")
}),
// webpack.prod.config
new webpack.DefinePlugin({
"FIREBASE_URL": JSON.stringify("https://myapp.firebaseio.com")
}),

Now, within my components anywhere that I reference FIREBASE_URL will be updated to the value created using DefinePlugin. NOTE: This will not create a global variable, so throwing in a debugger and trying to inspect the value of FIREBASE_URL won’t work. From what I understand, Webpack overwrites the reference using the supplied value as to avoid polluting the global scope.