Change hard coded url constants for different environments via webpack

前端 未结 2 424
情歌与酒
情歌与酒 2020-12-24 11:28

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

相关标签:
2条回答
  • 2020-12-24 12:10

    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.

    0 讨论(0)
  • 2020-12-24 12:28

    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.
    0 讨论(0)
提交回复
热议问题