通过 webpack 更改不同环境的硬编码 url 常量
Change hard coded url constants for different environments via webpack
我有一个 ApiCaller.js
模块,它生成对我们的 api 服务器的调用以获取数据。它有常量字段 API_URL 指向服务器 url。
此 API_URL const 更改 dev 和 prod 环境。
所以当我需要部署到 dev 环境时,我需要更改 url (API_URL ) 手动指向 dev-api-server ,反之亦然。
我想在代码之外使用这些配置参数,并且在构建过程中我想动态更改它们,以便我可以使用不同的设置进行构建。
我正在使用 webpack 来捆绑我的 javascript、html、css 文件。
您可以设置 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';
最坏的情况是 uglify 无法缩小条件表达式而保持原样。
您可以将 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(/*...*/);
(编辑)如果我有超过 production/development 个不同环境常量的配置?
假设您有 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
的一个对象中执行此操作 - 它看起来更干净。
我有一个 ApiCaller.js
模块,它生成对我们的 api 服务器的调用以获取数据。它有常量字段 API_URL 指向服务器 url。
此 API_URL const 更改 dev 和 prod 环境。
所以当我需要部署到 dev 环境时,我需要更改 url (API_URL ) 手动指向 dev-api-server ,反之亦然。
我想在代码之外使用这些配置参数,并且在构建过程中我想动态更改它们,以便我可以使用不同的设置进行构建。
我正在使用 webpack 来捆绑我的 javascript、html、css 文件。
您可以设置 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';
最坏的情况是 uglify 无法缩小条件表达式而保持原样。
您可以将 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(/*...*/);
(编辑)如果我有超过 production/development 个不同环境常量的配置?
假设您有 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
的一个对象中执行此操作 - 它看起来更干净。