web-dev-qa-db-fra.com

Modifier les constantes d'URL codées en dur pour différents environnements via le webpack

J'ai un ApiCaller.js module qui génère des appels à notre serveur api pour obtenir des données. Il a un champ const API_URL qui pointe vers l'url du serveur. Cette API_URL const change pour les environnements dev et prod.

Donc, lorsque je dois déployer dans un environnement dev, je dois modifier cette URL (API_URL) manuellement pour pointer vers dev-api-server et vice -versa.

Je veux ces paramètres de configuration en dehors du code et pendant le processus de construction, je veux les changer dynamiquement afin de pouvoir construire avec différents paramètres.

J'utilise webpack pour regrouper mes fichiers javascript, html, css.

28
WitVault

Vous pouvez stocker votre API_URL dans la configuration du 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]
        })
    ],
    // ...
}

Maintenant, dans votre ApiCaller, vous pouvez utiliser API_URL comme variable définie, qui sera différente selon process.env.NODE_ENV:

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

(modifier) ​​Si j'ai plus de configuration de production/développement pour différentes constantes d'environnement?

Imaginez que vous avez API_URL comme dans la réponse ci-dessus, API_URL_2 et API_URL_3 qui devrait prendre en charge différents paramètres d'environnement 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)
        })
    ],
    // ...
}

(modifier 2)

  1. Si vous passez une chaîne comme constante d'environnement, vous devez utiliser JSON.stringify.
  2. Vous n'avez pas besoin de définir new webpack.DefinePlugin plusieurs fois. Vous pouvez le faire dans un objet passé à new webpack.DefinePlugin - il a l'air plus propre.
39
Everettss

Vous pouvez définir define plugin pour définir une variable PRODUCTION comme suit (ou alternativement sur true si vous utilisez différents fichiers de configuration pour les builds):

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

Ensuite, dans votre code, vous écrirez quelque chose comme:

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

Lors de la compilation, le webpack remplacera PRODUCTION par sa valeur (donc true ou false), et cela devrait permettre à UglifyJS de minimiser notre expression:

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

Le pire des cas est que uglify ne puisse pas minimiser l'expression conditionnelle en la laissant telle quelle.

1
AssassinsMod