Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change hard coded url constants for different environments via webpack

People also ask

Does webpack use Node_env?

NODE_ENV=production just tells node in what mode to actually run webpack. Meaning, if you have code in your app which does... It will simply leave those in place. In order to make your output code reflect the proper NODE_ENV you have to use either the EnvironmentPlugin or the DefinePlugin.

What is devServer?

A dev server is typically an internal web server used for testing and running code in development. It is a web server.


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.

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.