如何管理不同环境的配置变量/常数?
这可以是一个例子:
我的其余API可以在localhost:7080/myapi/上访问,但是我的朋友在Git版本控制下使用相同的代码,他在localhost:8099/hisapi/上的Tomcat上部署了API。
假设我们有这样的东西:
angular
.module('app', ['ngResource'])
.constant('API_END_POINT','<local_end_point>')
.factory('User', function($resource, API_END_POINT) {
return $resource(API_END_POINT + 'user');
});
我如何动态地注入API端点的正确值,取决于环境?
在PHP中,我通常使用config.username.xml文件来完成这类工作,将基本配置文件(config.xml)与由用户名识别的本地环境配置文件合并。但我不知道如何在JavaScript中管理这种事情?
为了达到这个目的,我建议你使用AngularJS环境插件:https://www.npmjs.com/package/angular-environment
这里有一个例子:
angular.module('yourApp', ['environment']).
config(function(envServiceProvider) {
// set the domains and variables for each environment
envServiceProvider.config({
domains: {
development: ['localhost', 'dev.local'],
production: ['acme.com', 'acme.net', 'acme.org']
// anotherStage: ['domain1', 'domain2'],
// anotherStage: ['domain1', 'domain2']
},
vars: {
development: {
apiUrl: '//localhost/api',
staticUrl: '//localhost/static'
// antoherCustomVar: 'lorem',
// antoherCustomVar: 'ipsum'
},
production: {
apiUrl: '//api.acme.com/v2',
staticUrl: '//static.acme.com'
// antoherCustomVar: 'lorem',
// antoherCustomVar: 'ipsum'
}
// anotherStage: {
// customVar: 'lorem',
// customVar: 'ipsum'
// }
}
});
// run the environment check, so the comprobation is made
// before controllers and services are built
envServiceProvider.check();
});
然后,你可以从你的控制器调用变量,像这样:
envService.read('apiUrl');
希望能有所帮助。
为了达到这个目的,我建议你使用AngularJS环境插件:https://www.npmjs.com/package/angular-environment
这里有一个例子:
angular.module('yourApp', ['environment']).
config(function(envServiceProvider) {
// set the domains and variables for each environment
envServiceProvider.config({
domains: {
development: ['localhost', 'dev.local'],
production: ['acme.com', 'acme.net', 'acme.org']
// anotherStage: ['domain1', 'domain2'],
// anotherStage: ['domain1', 'domain2']
},
vars: {
development: {
apiUrl: '//localhost/api',
staticUrl: '//localhost/static'
// antoherCustomVar: 'lorem',
// antoherCustomVar: 'ipsum'
},
production: {
apiUrl: '//api.acme.com/v2',
staticUrl: '//static.acme.com'
// antoherCustomVar: 'lorem',
// antoherCustomVar: 'ipsum'
}
// anotherStage: {
// customVar: 'lorem',
// customVar: 'ipsum'
// }
}
});
// run the environment check, so the comprobation is made
// before controllers and services are built
envServiceProvider.check();
});
然后,你可以从你的控制器调用变量,像这样:
envService.read('apiUrl');
希望能有所帮助。
好问题!
一种解决方案是继续使用config.xml文件,并从后端向生成的html提供api端点信息,如下所示(以php为例):
<script type="text/javascript">
angular.module('YourApp').constant('API_END_POINT', '<?php echo $apiEndPointFromBackend; ?>');
</script>
也许不是一个漂亮的解决方案,但它会起作用。
另一种解决方案可能是保持API_END_POINT常量值,因为它应该在生产环境中,并且只修改您的hosts-file来将url指向您的本地api。
或者使用localStorage来重写,就像这样:
.factory('User',['$resource','API_END_POINT'],function($resource,API_END_POINT){
var myApi = localStorage.get('myLocalApiOverride');
return $resource((myApi || API_END_POINT) + 'user');
});
我们也可以这样做。
(function(){
'use strict';
angular.module('app').service('env', function env() {
var _environments = {
local: {
host: 'localhost:3000',
config: {
apiroot: 'http://localhost:3000'
}
},
dev: {
host: 'dev.com',
config: {
apiroot: 'http://localhost:3000'
}
},
test: {
host: 'test.com',
config: {
apiroot: 'http://localhost:3000'
}
},
stage: {
host: 'stage.com',
config: {
apiroot: 'staging'
}
},
prod: {
host: 'production.com',
config: {
apiroot: 'production'
}
}
},
_environment;
return {
getEnvironment: function(){
var host = window.location.host;
if(_environment){
return _environment;
}
for(var environment in _environments){
if(typeof _environments[environment].host && _environments[environment].host == host){
_environment = environment;
return _environment;
}
}
return null;
},
get: function(property){
return _environments[this.getEnvironment()].config[property];
}
}
});
})();
在你的控制器/服务中,我们可以注入依赖项并调用get方法来访问属性。
(function() {
'use strict';
angular.module('app').service('apiService', apiService);
apiService.$inject = ['configurations', '$q', '$http', 'env'];
function apiService(config, $q, $http, env) {
var service = {};
/* **********APIs **************** */
service.get = function() {
return $http.get(env.get('apiroot') + '/api/yourservice');
};
return service;
}
})();
$http.get(env.get('apiroot')将根据主机环境返回url。