简体   繁体   English

通过webpack更改不同环境的硬编码URL常量

[英]Change hard coded url constants for different environments via webpack

I have a ApiCaller.js module which generate calls to our api server to get data. 我有一个ApiCaller.js模块,它生成对我们的api服务器的调用以获取数据。 It has const field API_URL which points to server url. 它有const字段API_URL ,它指向服务器url。 This API_URL const changes for dev and prod environments. API_URL const针对devprod环境进行更改。

So when I need to deploy to dev environment I need to change that url ( API_URL ) manually to point to dev-api-server and vice-versa. 因此,当我需要部署到开发环境时,我需要手动更改该URL( API_URL )以指向dev-api-server ,反之亦然。

I want these configuration parameters outside the code and during build process I want to change them dynamically so that I can build with different settings. 我想在代码之外的这些配置参数,并在构建过程中我想动态更改它们,以便我可以使用不同的设置进行构建。

I am using webpack to bundle my javascript, html, css files. 我正在使用webpack捆绑我的javascript,html,css文件。

You can store your API_URL in webpack config: 您可以将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]
        })
    ],
    // ...
}

Now in your ApiCaller you can use API_URL as defined variable, which it will be different depend on process.env.NODE_ENV : 现在在您的ApiCaller您可以将API_URL用作定义的变量,它将根据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 想象一下,您有API_URL如上面的答案, API_URL_2API_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)
        })
    ],
    // ...
}

(edit 2) (编辑2)

  1. If you pass string as a environment constant you should use JSON.stringify . 如果将字符串作为环境常量传递,则应使用JSON.stringify
  2. You don't need to define new webpack.DefinePlugin multiple times. 您不需要多次定义new webpack.DefinePlugin You can do it in one object passed to new webpack.DefinePlugin - it looks cleaner. 你可以在传递给new webpack.DefinePlugin一个对象中new webpack.DefinePlugin - 它看起来更干净。

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): 您可以设置define插件以定义PRODUCTION变量,如下所示(或者,如果对构建使用不同的配置文件,则为true ):

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: 在编译期间,webpack将用其值替换PRODUCTION (无论是true还是false ),这应该允许UglifyJS缩小我们的表达式:

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. 最糟糕的情况是uglify无法缩小条件表达式,使其保持原样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM