Изменение жестко закодированных констант url для различных сред с помощью webpack
У меня есть модуль ApiCaller.js
, который генерирует вызовы к нашему api-серверу для получения данных. Он имеет поле const API_URL, которое указывает на url сервера.
Это API_URL const изменяется для dev и prod сред.
Мне нужны эти параметры конфигурации вне кода и во время сборки процесс я хочу изменить их динамически, чтобы я мог строить с различными настройками.
Я использую webpack для связывания моих javascript, html, css файлов.
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)
- Если вы передайте строку в качестве константы окружения, которую вы должны использовать
JSON.stringify
.- Вам не нужно определять
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';
Наихудший сценарий-это уродство, не способное минимизировать условное выражение, оставляющее все как есть.