Change hard coded url constants for different environments via webpack Change hard coded url constants for different environments via webpack javascript javascript

Change hard coded url constants for different environments via webpack


You can store your API_URL in webpack config:

// this config can be in webpack.config.js or other file with constantsvar API_URL = {    production: JSON.stringify('prod-url'),    development: JSON.stringify('dev-url')}// check environment modevar environment = process.env.NODE_ENV === 'production' ? 'production' : 'development';// webpack configmodule.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 settingvar 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 settingsvar mapEnvToSettings = function (settingsConsts) {     return settingsConsts[environment()];};// special map for not supported all production/development/test settingsvar 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 configmodule.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.


You could set the define plugin to define a PRODUCTION variable as follows (or alternatively to true if you use different configuration files for the builds):

new webpack.DefinePlugin({    PRODUCTION: process.env.NODE_ENV === 'production'})

Then in your code you will write something like:

var API_URL = PRODUCTION ? 'my-production-url' : 'my-development-url';

During compilation webpack will replace PRODUCTION with its value (so either true or false), and this should allow UglifyJS to minify our expression:

var API_URL = <true/false> ? 'my-production-url' : 'my-development-url';

The worst case scenario is uglify not being able to minify the conditional expression leaving it as is.