loading...

Using DefinePlugin to Define API URLs in Webpack

_hridaysharma profile image Hridayesh Sharma ・2 min read

In today's development cycle, there are multiple environments for any API. For example, the dev API is available at dev.domain.com and production API is available at prod.domain.com.
While writing a front end library or a front end modern JavaScript application that consumes the API we use webpack to build our applications. For each environment (dev or prod) we write a different npm script to build application for that environment.
package.json

... any other configuration
"scripts": {
    "dev": "webpack --env=dev --mode=development",
    "prod": "webpack --env=prod --mode=development"
  },
...rest of file

Now let's say our code consumes an API ${env}.domain.com where env can be either dev or prod or any other environment that our API is available at.

JavaScript Code

 // this code gets some data from the api
let url = `http://dev.domain.com`
fetch(url)
  .then(response => response.json())
  .then(res => console.log(res))

So how do we make the fetch to make a request to prod.domain.com instead of dev.domain.com when we build our application for production??

We will use a webpack plugin called DefinePlugin to achieve this.
So let's write our webpack configuration and then we will modify the JavaScript Code above to work in different environments.

webpack.config.js

const path = require('path'
const webpack = require('webpack')
/* we are creating our webpack configure as a function that takes env 
as parameter which is passed from npm scripts and can be dev or prod 
as defined in npm scripts
*/
module.exports = (env) => {
 const envConfig = {}
  switch(env) {
    case 'dev': 
      envConfig.domain: 'http://dev.domain.com'
    case 'prod'
      envConfig.domain: 'http://prod.domain.com'
  }

  return {
    entry: path.resolve(__dirname, './src/index.js')
    output: {
      path: path.resolve(__dirname, 'dist')
      filename: 'bundle.js'
    },
    plugins: [
      new DefinePlugin({
        API_DOMAIN: JSON.stringify(envConfig.domain)
      })
   ]
  }
}
Let's see what we just did in our webpack configuration

We just created our webpack configuration and inside it an object envConfig that contains a domain property on it. Depending upon what's the value of env, the value of domain will vary.
Then we used DefinePlugin to define a API_DOMAIN constant. Now in our code this API_DOMAIN can be used and we do not have to worry about the url that we used in our JavaScript code.

Modified JavaScript Code

  let url = API_DOMAIN
  fetch(url)
  .then(response => response.json())
  .then(res => console.log(res))

PS: I have added switch statement in the webpack file itself for clarity. You can add the logic in a separate file and then import it in the webpack configuration.

That's how we can use webpack to handle the API domains for us based on the environment we are building our code for. Similarly we can have any other constants configured as well.

The GitHub repository for the code is available at Webpack Manage Environment Domains

Posted on by:

Discussion

markdown guide