Todavía me encantaría saber cómo pude haber encontrado el lugar en nuestro código fuente que causó este problema, pero desde entonces he podido encontrar el problema manualmente.
Había una función de controlador declarada en el ámbito global, en lugar de usar una .controller()
llamada en el módulo de la aplicación.
Entonces había algo como esto:
function SomeController( $scope, i18n ) { /* ... */ }
Esto funciona bien para AngularJS, pero para que funcione correctamente con la manipulación, tuve que cambiarlo a:
var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );
Después de más pruebas, encontré casos de más controladores que también causaron problemas. Así es como encontré la fuente de todos ellos manualmente :
En primer lugar, considero bastante importante habilitar el embellecimiento de salida en las opciones de uglify. Para nuestra dura tarea eso significaba:
options : {
beautify : true,
mangle : true
}
Luego abrí el sitio web del proyecto en Chrome, con DevTools abierto. Lo que da como resultado que se registre un error como el siguiente:
El método en el seguimiento de llamadas que nos interesa es el que marqué con una flecha. Esto está providerInjector
eninjector.js
. Querrá colocar un punto de interrupción donde arroje una excepción:
Cuando vuelva a ejecutar la aplicación, se alcanzará el punto de interrupción y podrá saltar la pila de llamadas. Habrá una llamada desde invoke
adentroinjector.js
, reconocible desde la cadena "Token de inyección incorrecto":
El locals
parámetro (alterado d
en mi código) da una idea bastante buena sobre qué objeto en su fuente es el problema:
Un rápido grep
vistazo a nuestra fuente encuentra muchas instancias de modalInstance
, pero a partir de ahí, fue fácil encontrar este lugar en la fuente:
var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};
Que debe cambiarse a:
var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];
En caso de que la variable no contenga información útil, también puede saltar más en la pila y debe hacer una llamada a la invoke
que debe tener sugerencias adicionales:
Evita que esto vuelva a suceder
Ahora que, con suerte, ha encontrado el problema, creo que debería mencionar la mejor forma de evitar que esto vuelva a suceder en el futuro.
Obviamente, puede usar la anotación de matriz en línea en todas partes, o la $inject
anotación de propiedad (según su preferencia) y simplemente tratar de no olvidarse de ella en el futuro. Si lo hace, asegúrese de habilitar el modo de inyección de dependencia estricta para detectar errores como este antes de tiempo.
¡Cuidado! En caso de que esté utilizando Angular Batarang, StrictDI podría no funcionar para usted, ya que Angular Batarang inyecta código no anotado en el suyo (¡Bad Batarang!).
O puede dejar que ng-annotate se encargue de ello. Recomiendo encarecidamente hacerlo, ya que elimina una gran cantidad de posibles errores en esta área, como:
- Falta la anotación DI
- Anotación DI incompleta
- Anotación DI en orden incorrecto
Mantener las anotaciones actualizadas es simplemente un dolor de cabeza y no debería tener que hacerlo si se puede hacer automáticamente. ng-annotate hace exactamente eso.
Debería integrarse muy bien en su proceso de compilación con grunt-ng-annotate y gulp-ng-annotate .