Изменение жестко закодированных констант url для различных сред с помощью webpack


У меня есть модуль ApiCaller.js, который генерирует вызовы к нашему api-серверу для получения данных. Он имеет поле const API_URL, которое указывает на url сервера. Это API_URL const изменяется для dev и prod сред.

Поэтому, когда мне нужно развернуть вdev среду, мне нужно вручную изменить этот url (API_URL ), чтобы указать наdev-api-сервер и наоборот.

Мне нужны эти параметры конфигурации вне кода и во время сборки процесс я хочу изменить их динамически, чтобы я мог строить с различными настройками.

Я использую webpack для связывания моих javascript, html, css файлов.

2 24

2 ответа:

Вы можете сохранить ваш API_URL в 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]
        })
    ],
    // ...
}

Теперь в вашем ApiCaller Вы можете использовать API_URL как определенную переменную, которая будет отличаться в зависимости от process.env.NODE_ENV:

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

(edit) если у меня есть больше, чем production/development config для различных констант среды?

Представьте, что у вас есть API_URL, как в приведенном выше ответе, API_URL_2 и API_URL_3 , которые должны поддерживать различные настройки среды 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)
        })
    ],
    // ...
}

(правка 2)

  1. Если вы передайте строку в качестве константы окружения, которую вы должны использовать JSON.stringify.
  2. Вам не нужно определять new webpack.DefinePlugin несколько раз. Вы можете сделать это в одном объекте, переданном в new webpack.DefinePlugin - он выглядит чище.

Вы можете задать define plugin для определения переменной PRODUCTION следующим образом (или альтернативно true, Если вы используете разные конфигурационные файлы для сборки):

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

Тогда в коде вы напишете что-то вроде:

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

Во время компиляции webpack заменит PRODUCTION своим значением (так что либо true, либо false), и это должно позволить UglifyJS минимизировать наше выражение:

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

Наихудший сценарий-это уродство, не способное минимизировать условное выражение, оставляющее все как есть.