J'adorerais toujours savoir comment j'aurais pu trouver l'emplacement dans notre code source qui a causé ce problème, mais j'ai depuis pu trouver le problème manuellement.
Il y avait une fonction de contrôleur déclarée sur la portée globale, au lieu d'utiliser un .controller()
appel sur le module d'application.
Il y avait donc quelque chose comme ça:
function SomeController( $scope, i18n ) { /* ... */ }
Cela fonctionne très bien pour AngularJS, mais pour que cela fonctionne correctement avec le mangling, j'ai dû le changer en:
var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );
Après d'autres tests, j'ai trouvé des instances de plusieurs contrôleurs qui ont également causé des problèmes. Voici comment j'ai trouvé la source de chacun d'eux manuellement :
Tout d'abord, je considère qu'il est assez important d'activer l'embellissement de la sortie dans les options uglify. Pour notre tâche difficile, cela signifiait:
options : {
beautify : true,
mangle : true
}
J'ai ensuite ouvert le site Web du projet dans Chrome, avec les DevTools ouverts. Ce qui entraîne une erreur comme celle ci-dessous enregistrée:
La méthode de la trace d'appel qui nous intéresse est celle que j'ai marquée d'une flèche. C'est providerInjector
dansinjector.js
. Vous allez vouloir placer un point d'arrêt où il lève une exception:
Lorsque vous réexécutez maintenant l'application, le point d'arrêt est atteint et vous pouvez sauter dans la pile d'appels. Il y aura un appel de invoke
ininjector.js
, reconnaissable à partir de la chaîne "Jeton d'injection incorrect":
Le locals
paramètre (mutilé d
dans mon code) donne une assez bonne idée de quel objet dans votre source est le problème:
Un rapide grep
sur notre source trouve de nombreuses instances de modalInstance
, mais à partir de là, il était facile de trouver cet endroit dans la source:
var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};
Qui doit être changé en:
var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];
Dans le cas où la variable ne contient pas d'informations utiles, vous pouvez également sauter plus haut dans la pile et vous devriez frapper un appel invoke
qui devrait avoir des indices supplémentaires:
Empêcher que cela ne se reproduise
Maintenant que vous avez trouvé le problème avec un peu de chance, je pense que je devrais mentionner la meilleure façon d'éviter que cela ne se reproduise à l'avenir.
De toute évidence, vous pouvez simplement utiliser l' annotation de tableau en ligne partout, ou l' $inject
annotation de propriété (selon vos préférences) et essayer simplement de ne pas l'oublier à l'avenir. Si vous le faites, assurez-vous d'activer le mode d'injection de dépendances strict , pour détecter les erreurs comme celle-ci tôt.
Fais attention! Si vous utilisez Angular Batarang, StrictDI pourrait ne pas fonctionner pour vous, car Angular Batarang injecte du code non annoté dans le vôtre (mauvais Batarang!).
Ou vous pouvez laisser ng-annotate s'en occuper. Je recommande vivement de le faire, car cela supprime beaucoup de risques d'erreurs dans ce domaine, comme:
- Annotation DI manquante
- Annotation DI incomplète
- Annotation DI dans le mauvais ordre
Garder les annotations à jour est tout simplement une douleur dans le cul et vous ne devriez pas avoir à le faire si cela peut être fait automatiquement. ng-annotate fait exactement cela.
Il devrait s'intégrer parfaitement dans votre processus de construction avec grunt-ng-annotate et gulp-ng-annotate .