Ainda adoraria saber como poderia ter encontrado o local em nosso código-fonte que causou esse problema, mas desde então consegui encontrar o problema manualmente.
Havia uma função de controlador declarada no escopo global, em vez de usar uma .controller()
chamada no módulo de aplicativo.
Então, havia algo assim:
function SomeController( $scope, i18n ) { /* ... */ }
Isso funciona bem para o AngularJS, mas para que funcione bem com mutilação, eu tive que alterá-lo para:
var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );
Depois de mais testes, eu realmente encontrei instâncias de mais controladores que também causaram problemas. Foi assim que encontrei a fonte de todos eles manualmente :
Em primeiro lugar, considero bastante importante habilitar o embelezamento da saída nas opções do uglify. Para nossa tarefa árdua, isso significava:
options : {
beautify : true,
mangle : true
}
Em seguida, abri o site do projeto no Chrome, com as DevTools abertas. O que resulta em um erro como o seguinte sendo registrado:
O método no rastreamento de chamada em que estamos interessados é aquele que marquei com uma seta. Isso está providerInjector
dentroinjector.js
. Você vai querer colocar um ponto de interrupção onde ele lança uma exceção:
Quando você executar novamente o aplicativo, o ponto de interrupção será atingido e você poderá saltar para cima na pilha de chamadas. Haverá uma chamada de invoke
eminjector.js
, reconhecível na string "Token de injeção incorreto":
O locals
parâmetro (mutilado d
em meu código) dá uma boa ideia sobre qual objeto em sua fonte está o problema:
Uma rápida olhada grep
em nossa fonte encontra muitas instâncias de modalInstance
, mas, a partir daí, foi fácil encontrar este ponto na fonte:
var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};
Que deve ser alterado para:
var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];
Caso a variável não contenha informações úteis, você também pode pular para cima na pilha e deve acertar uma chamada para a invoke
qual deve ter dicas adicionais:
Evite que isso aconteça novamente
Agora que espero que você tenha encontrado o problema, sinto que devo mencionar a melhor forma de evitar que isso aconteça novamente no futuro.
Obviamente, você poderia apenas usar a anotação de array embutido em qualquer lugar ou (dependendo de sua preferência) $inject
anotação de propriedade e simplesmente tentar não se esquecer disso no futuro. Se você fizer isso, certifique-se de habilitar o modo de injeção de dependência estrita para detectar erros como este antecipadamente.
Cuidado! Caso você esteja usando o Angular Batarang, o StrictDI pode não funcionar para você, pois o Angular Batarang injeta código não anotado no seu (Batarang ruim!).
Ou você pode deixar o ng-annotate cuidar disso. Eu recomendo fortemente fazer isso, pois remove muito potencial de erros nesta área, como:
- Anotação DI ausente
- Anotação DI incompleta
- Anotação DI na ordem errada
Manter as anotações atualizadas é simplesmente um pé no saco e você não deveria ter que fazer isso se puder ser feito automaticamente. ng-annotate faz exatamente isso.
Ele deve se integrar perfeitamente ao seu processo de construção com grunt-ng-annotate e gulp-ng-annotate .