Como você gerencia variáveis / constantes de configuração para diferentes ambientes?
Este poderia ser um exemplo:
Minha API de descanso está acessível localhost:7080/myapi/
, mas meu amigo que trabalha no mesmo código sob o controle de versão do Git tem a API implantada em seu Tomcat localhost:8099/hisapi/
.
Supondo que temos algo parecido com isto:
angular
.module('app', ['ngResource'])
.constant('API_END_POINT','<local_end_point>')
.factory('User', function($resource, API_END_POINT) {
return $resource(API_END_POINT + 'user');
});
Como injeto dinamicamente o valor correto do terminal da API, dependendo do ambiente?
No PHP, geralmente faço esse tipo de coisa com um config.username.xml
arquivo, mesclando o arquivo de configuração básica (config.xml) com o arquivo de configuração do ambiente local reconhecido pelo nome do usuário. Mas não sei como gerenciar esse tipo de coisa em JavaScript?
fonte
'ngconstant:development'
em'serve'
- se você colocá-lo na configuração do relógio sob a'gruntfile'
comotasks: ['ngconstant:development']
- você não precisará reiniciargrunt serve
quando você atualizar as variáveis de desenvolvimento na gruntfile.package: grunt.file.readJSON('development.json')
Uma solução interessante pode ser a separação de todos os valores específicos do ambiente em algum módulo angular separado, do qual todos os outros módulos dependem:
Em seguida, seus módulos que precisam dessas entradas podem declarar uma dependência:
Agora você pode pensar em outras coisas legais:
O módulo, que contém a configuração, pode ser separado em configuration.js, que será incluído na sua página.
Esse script pode ser facilmente editado por cada um de vocês, contanto que você não verifique este arquivo separado no git. Mas é mais fácil não verificar a configuração se ela estiver em um arquivo separado. Além disso, você pode ramificá-lo localmente.
Agora, se você tiver um sistema de compilação, como ANT ou Maven, suas etapas adicionais poderão implementar alguns espaços reservados para os valores API_END_POINT, que serão substituídos durante o tempo de compilação pelos seus valores específicos.
Ou você tem o seu
configuration_a.js
econfiguration_b.js
e decidir no backend que incluir.fonte
Para usuários do Gulp , gulp-ng-constant também é útil combinado com gulp-concat , event-stream e yargs .
Na minha pasta de configuração, tenho estes arquivos:
Então você pode executar
gulp config --env development
e isso criará algo como isto:Eu também tenho esta especificação:
fonte
Para conseguir isso, sugiro que você use o Plug-in de ambiente AngularJS: https://www.npmjs.com/package/angular-environment
Aqui está um exemplo:
E então, você pode chamar as variáveis de seus controladores como este:
Espero que ajude.
fonte
angular-environment
detecta o ambiente? ou seja, o que você precisa fazer no seu computador / servidor da web local para que ele saiba que é dev / prod, respectivamente?envServiceProvider.check()
... definirá automaticamente o ambiente apropriado com base nos domínios especificados". Então eu acho que ele detecta o domínio atual e define o ambiente adequadamente - é hora de testá-lo!Você pode usar
lvh.me:9000
para acessar o aplicativo AngularJS (lvh.me
apenas aponta para 127.0.0.1) e, em seguida, especificar um terminal diferente selvh.me
for o host:E, em seguida, injete o serviço de configuração e use
Configuration.API
sempre que precisar acessar a API:Um pouco desajeitado, mas funciona bem para mim, embora em uma situação um pouco diferente (os pontos de extremidade da API diferem em produção e desenvolvimento).
fonte
window.location.host
era mais do que suficiente para mim.Nós também poderíamos fazer algo assim.
E no seu
controller/service
, podemos injetar a dependência e chamar o método get com a propriedade a ser acessada.$http.get(env.get('apiroot')
retornaria o URL com base no ambiente host.fonte
Boa pergunta!
Uma solução poderia ser continuar usando o arquivo config.xml e fornecer informações sobre o ponto de extremidade da API do backend para o html gerado, como este (exemplo em php):
Talvez não seja uma solução bonita, mas funcionaria.
Outra solução poderia ser manter o
API_END_POINT
valor constante como deveria estar em produção e modificar apenas o arquivo host para apontar esse URL para a API local.Ou talvez uma solução usando
localStorage
substituições, como esta:fonte
Muito tarde para o encadeamento, mas uma técnica que usei, pré-Angular, é aproveitar o JSON e a flexibilidade do JS para fazer referência dinâmica às chaves de coleção e usar fatos inalienáveis do ambiente (nome do servidor host, idioma atual do navegador , etc.) como entradas para discriminar / preferir seletivamente nomes-chave com sufixo em uma estrutura de dados JSON.
Isso fornece não apenas o contexto do ambiente de implantação (por OP), mas qualquer contexto arbitrário (como a linguagem) para fornecer o i18n ou qualquer outra variação necessária simultaneamente e (idealmente) em um único manifesto de configuração, sem duplicação e claramente óbvio.
EM MAIS DE 10 LINHAS VANILLA JS
Exemplo excessivamente simplificado, mas clássico: um URL base do terminal da API em um arquivo de propriedades formatado em JSON que varia de acordo com o ambiente em que (natch) o servidor host também varia:
Uma chave para a função de discriminação é simplesmente o nome do host do servidor na solicitação.
Naturalmente, isso pode ser combinado com uma chave adicional com base nas configurações de idioma do usuário:
O escopo da discriminação / preferência pode ser limitado a chaves individuais (como acima), onde a chave "base" é substituída apenas se houver uma chave correspondente + sufixo para as entradas da função - ou uma estrutura inteira, e essa estrutura em si. analisado recursivamente para combinar sufixos de discriminação / preferência:
Assim, se um usuário visitar o site da produção tem Alemão ( de ) configuração de preferência de idioma, a configuração acima entraria em colapso para:
Como é uma função mágica de reescrita de JSON de preferência / discriminação? Não muito:
Em nossas implementações, que incluem sites Angular e pré-Angular, simplesmente inicializamos a configuração bem antes de outras chamadas de recursos, colocando o JSON dentro de um fechamento JS auto-executável, incluindo a função prefer (), e alimentamos propriedades básicas de hostname e código de idioma (e aceita quaisquer sufixos arbitrários adicionais que você possa precisar):
Um site pré-angular teria agora de Reduzido (teclas sufixo há @) window.app_props se referir.
Um site Angular, como uma etapa de bootstrap / init, simplesmente copia o objeto props descartado para $ rootScope e (opcionalmente) o destrói do escopo global / window
para ser posteriormente injetado nos controladores:
ou referido de ligações em visualizações:
Ressalvas? O caractere @ não é válido para nomeação de variável / chave JS / JSON, mas até agora aceito. Se isso for um rompimento de um contrato, substitua qualquer convenção que você goste, como "__" (sublinhado duplo), desde que você cumpra.
A técnica pode ser aplicada no servidor, portada para Java ou C #, mas sua eficiência / compactação pode variar.
Como alternativa, a função / convenção pode fazer parte do seu script de compilação de front-end, para que o JSON sangrento de todo o ambiente / todos os idiomas nunca seja transmitido por fio.
ATUALIZAR
Desenvolvemos o uso dessa técnica para permitir vários sufixos em uma chave, para evitar ser forçado a usar coleções (você ainda pode, tão profundamente quanto quiser) e também para honrar a ordem dos sufixos preferidos.
Exemplo (veja também jsFiddle de trabalho ):
1/2 (uso básico) prefere as teclas '@dev', descarta todas as outras chaves com sufixo
3 prefere '@dev' sobre '@fr', prefere '@ dev & fr' sobre todos os outros
4 (igual a 3, mas prefere '@fr' em vez de '@dev')
5 sem sufixos preferidos, descarta TODAS as propriedades com sufixo
Isso é feito marcando cada propriedade com sufixo e promovendo o valor de uma propriedade com sufixo para a propriedade sem sufixo ao iterar sobre as propriedades e encontrar um sufixo com pontuação mais alta.
Algumas eficiências nesta versão, incluindo a remoção da dependência do JSON para cópia em profundidade e a recorrência apenas em objetos que sobrevivem à rodada de pontuação em profundidade:
fonte
Se você estiver usando o Brunch , o plug-in Constangular ajuda a gerenciar variáveis para diferentes ambientes.
fonte
Você já viu essa pergunta e sua resposta?
Você pode definir um valor válido globalmente para seu aplicativo como este:
e depois use-o em seus serviços. Você pode mover esse código para um arquivo config.js e executá-lo no carregamento da página ou em outro momento conveniente.
fonte