WitVault WitVault - 1 year ago 108
Javascript Question

Change hard coded url constants for different environments via webpack

I have a

ApiCaller.js
module which generate calls to our api server to get data. It has const field API_URL which points to server url.
This API_URL const changes for dev and prod environments.

So when I need to deploy to dev environment I need to change that url (API_URL) manually to point to dev-api-server and vice-versa.

I want these configuration parameters outside the code and during build process I want to change them dynamically so that I can build with different settings.

I am using webpack to bundle my javascript, html, css files.

Answer Source

You can store your API_URL in webpack config:

// this config can be in webpack.config.js or other file with constants
var API_URL = {
    production: JSON.stringify('prod-url'),
    development: JSON.stringify('dev-url')
}

// check environment mode
var environment = process.env.NODE_ENV === 'production' ? 'production' : 'development';

// webpack config
module.exports = {
    // ...
    plugins: [
        new webpack.DefinePlugin({
            'API_URL': API_URL[environment]
        })
    ],
    // ...
}

Now in your ApiCaller you can use API_URL as defined variable, which it will be different depend on process.env.NODE_ENV:

ajax(API_URL).then(/*...*/);

(edit) If I have more than production/development config for different environment constants?

Imagine that you have API_URL like in above answer, API_URL_2 and API_URL_3 which should support different environment settings production/development/test

var API_URL = {
    production: JSON.stringify('prod-url'),
    development: JSON.stringify('dev-url')
};

var API_URL_2 = {
    production: JSON.stringify('prod-url-2'),
    development: JSON.stringify('dev-url-2'),
    test: JSON.stringify('test-url-2')
};

var API_URL_3 = {
    production: JSON.stringify('prod-url-3'),
    development: JSON.stringify('dev-url-3'),
    test: JSON.stringify('test-url-3')
};

// get available environment setting
var environment = function () {
     switch(process.env.NODE_ENV) {
         case 'production':
             return 'production';
         case 'development':
             return 'development';
         case 'test':
             return 'test';
         default:                // in case ...
             return 'production';
     };
};

// default map for supported all production/development/test settings
var mapEnvToSettings = function (settingsConsts) {
     return settingsConsts[environment()];
};

// special map for not supported all production/development/test settings
var mapAPI_URLtoSettings = function () {
     switch(environment()) {
         case 'production':
             return API_URL.production;
         case 'development':
             return API_URL.development;
         case 'test':                    // don't have special test case
             return API_URL.development;
     };
};

// webpack config
module.exports = {
    // ...
    plugins: [
        new webpack.DefinePlugin({
            'API_URL': mapAPI_URLtoSettings(),
            'API_URL_2': mapEnvToSettings(API_URL_2),
            'API_URL_3': mapEnvToSettings(API_URL_3)
        })
    ],
    // ...
}

(edit 2)

  1. If you pass string as a environment constant you should use JSON.stringify.
  2. You don't need to define new webpack.DefinePlugin multiple times. You can do it in one object passed to new webpack.DefinePlugin - it looks cleaner.
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download