Подтвердить что ты не робот

Изменение жестко закодированных констант URL для разных сред через webpack

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

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

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

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

4b9b3361

Ответ 1

Вы можете сохранить API_URL в конфигурации webpack:

// 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) Если у меня больше, чем версия для разработки/разработки для разных констант среды?

Представьте, что у вас есть 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)

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

Ответ 2

Вы можете установить 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';

Худший вариант сценария - угадать неспособность минимизировать условное выражение, оставляя его как есть.