web-dev-qa-db-fra.com

Recherche de la cause des erreurs "fournisseur inconnu"

J'obtiens l'erreur suivante:

Error: [$injector:unpr] Unknown provider: nProvider <- n

Je sais que cela est dû au processus de minification et je comprends pourquoi. Cependant, existe-t-il un moyen facile de déterminer quel fichier est réellement à l'origine du problème?

39
Brett Postin

Angular 1.3.x a une directive ng-strict-di qui est placée sur le même élément que la directive ng-app. Cet élément provoque une erreur de votre application lorsque les dépendances n'ont pas été annotées. Bien qu'il ne vous donne toujours pas le numéro de ligne du code incriminé, il vous donne la fonction avec ses paramètres (c'est-à-dire la fonction ($ scope, myServiceName)) qui est, espérons-le, assez unique pour que vous puissiez la trouver assez rapidement dans un bon éditer le code.

Un bon aperçu de la directive: ng-strict-di .

27
ansorensen

Je comprends la question et j'ai une réponse, elle n'est que légèrement alambiquée.

La façon dont j'ai trouvé le problème était de renommer tous les identifiants pour les rendre tous uniques, puis vous obtenez quelque chose d'utile à rechercher dans votre javascript compilé qui, nous l'espérons, vous dirigera vers le coupable.

télécharger ma version modifiée de glify (pull request en attente ...)

brew install node si aucun nœud n'est installé.

./bin/uglifyjs --unique_ids original.min.js >new.min.js

Remplacez maintenant votre js compilé par new.min.js et chargez votre application pour reproduire le problème maintenant, vous devriez obtenir une erreur d'injection de dépendance comme n4536

Si votre éditeur est génial avec des lignes super longues, vous pouvez simplement charger new.min.js, recherchez n4536 et j'espère que cela vous aidera à identifier le coupable.

Sinon, cela fonctionnera pour imprimer du contexte autour du problème. egrep -o '.{199}n4536.{99}' new.min.js

7
ark

L'injecteur d'Angular a 3 façons de résoudre les dépendances pour vous:

1. Inférence de dépendances à partir des noms d'arguments de fonction. C'est le plus utilisé dans tous les exemples angulaires, par ex.

app.controller('MyController', function($scope, MyService) { ... });

Dans ce cas, l'injecteur convertit la fonction en chaîne, analyse les noms d'arguments et recherche les services/usines/tout le reste correspondant à ce nom.

2. Annotations en ligne. Vous pourriez également rencontrer cette syntaxe:

app.controller('MyController', ['$scope', 'MyService', function($scope, MyService) { ... }]);

Dans ce cas, vous facilitez la tâche de l'injecteur, car vous énoncez explicitement les noms des dépendances dont vous avez besoin. Les noms sont placés entre guillemets et les minificateurs js ne modifient pas les chaînes dans le code.

. Annotations en ligne en tant que propriété. Si vous définissez vos contrôleurs en tant que fonctions, vous pouvez définir des annotations dans la propriété spéciale $inject:

function MyController($scope, MyService) {...}
MyController.$inject = ['$scope', 'MyService'];

Dans ce cas, nous indiquons également explicitement les dépendances.

Je suppose que vous utilisez la solution non. 1. Une fois que le minifieur a changé le nom de vos dépendances implicitement définies, l'injecteur ne sait plus quelles sont les dépendances de votre fonction. Pour surmonter cela, vous devez utiliser la 2e ou la 3e façon d'annoter les dépendances.

6
package

Bien qu'il ne semble pas y avoir de moyen efficace pour déboguer ces problèmes DI si vous ne savez pas où chercher, j'avais le sentiment que le mien était dans un endroit moins qu'évident ... et c'était:

App.Services = angular.module('spokenvote.services', ['ngResource', 'ngCookies'])
    .config(servicesConfig)
    .run(($rootScope, $location) -> $rootScope.location = $location)

devait être:

App.Services = angular.module('spokenvote.services', ['ngResource', 'ngCookies'])
    .config(servicesConfig)
    .run(['$rootScope', '$location', ($rootScope, $location) -> $rootScope.location = $location])
3
Kim Miller