Wenn ich die minimierte (über UglifyJS) Version meiner AngularJS-Anwendung lade, wird in der Konsole der folgende Fehler angezeigt:
Unknown provider: aProvider <- a
Jetzt ist mir klar, dass dies auf das Mangeln von Variablennamen zurückzuführen ist. Die entwirrte Version funktioniert einwandfrei. Aber ich tun möchte Verwendung von Variablennamen Mangeln machen, wie es drastisch die Größe unserer JS Ausgabedatei reduziert.
Aus diesem Grund verwenden wir ngmin in unserem Erstellungsprozess, aber es scheint dieses Problem nicht zu lösen, obwohl es uns in der Vergangenheit gute Dienste geleistet hat.
Um dieses Problem zu beheben, habe ich Quellkarten in unserer uglify-Grunzaufgabe aktiviert. Sie entstehen nur gut und Chrome tut laden die Karten vom Server. Trotzdem erhalte ich immer noch die gleiche nicht hilfreiche Fehlermeldung, obwohl ich den Eindruck hatte, dass ich jetzt den ursprünglichen Namen des Anbieters sehen sollte.
Wie kann ich Chrome dazu bringen, anhand der Quellkarten zu ermitteln, welcher Anbieter hier das Problem ist, oder wie kann ich den Anbieter auf andere Weise ermitteln?
quelle
Antworten:
Ich würde immer noch gerne wissen, wie ich den Ort in unserem Quellcode hätte finden können, der dieses Problem verursacht hat, aber seitdem konnte ich das Problem manuell finden.
Es wurde eine Controller-Funktion für den globalen Bereich deklariert, anstatt einen
.controller()
Aufruf für das Anwendungsmodul zu verwenden.Es gab also so etwas:
Dies funktioniert gut für AngularJS, aber damit es beim Mangeln richtig funktioniert, musste ich es ändern in:
Nach weiteren Tests fand ich tatsächlich Instanzen von mehr Controllern, die ebenfalls Probleme verursachten. So habe ich die Quelle aller manuell gefunden :
Zunächst halte ich es für ziemlich wichtig, die Verschönerung der Ausgabe in den uglify-Optionen zu aktivieren. Für unsere Grunzaufgabe bedeutete das:
Ich habe dann die Projektwebsite in Chrome mit geöffneten DevTools geöffnet. Was dazu führt, dass ein Fehler wie der folgende protokolliert wird:
Die Methode in der Anrufverfolgung, an der wir interessiert sind, ist die, die ich mit einem Pfeil markiert habe. Das ist
providerInjector
ininjector.js
. Sie möchten einen Haltepunkt platzieren, an dem eine Ausnahme ausgelöst wird:Wenn Sie die Anwendung jetzt erneut ausführen, wird der Haltepunkt erreicht und Sie können den Aufrufstapel hochspringen. Es erfolgt ein Anruf von
invoke
ininjector.js
, erkennbar an der Zeichenfolge "Falsches Injektionstoken":Der
locals
Parameter (d
in meinem Code entstellt ) gibt eine ziemlich gute Vorstellung davon, welches Objekt in Ihrer Quelle das Problem ist:Ein kurzer Blick
grep
auf unsere Quelle findet viele Beispiele vonmodalInstance
, aber von dort aus war es einfach, diesen Punkt in der Quelle zu finden:Welches muss geändert werden zu:
Falls die Variable keine nützlichen Informationen enthält, können Sie auch weiter nach oben springen und einen Aufruf ausführen,
invoke
der zusätzliche Hinweise enthalten sollte:Verhindern Sie, dass dies erneut geschieht
Nachdem Sie das Problem hoffentlich gefunden haben, sollte ich erwähnen, wie Sie am besten verhindern können, dass dies in Zukunft erneut auftritt.
Natürlich können Sie einfach die Inline-Array-Annotation überall oder die (je nach Ihren Präferenzen)
$inject
Eigenschafts-Annotation verwenden und einfach versuchen, sie in Zukunft nicht zu vergessen. Wenn Sie dies tun, stellen Sie sicher, dass Sie den strengen Abhängigkeitsinjektionsmodus aktivieren, um solche Fehler frühzeitig zu erkennen.Oder Sie können ng-annotate sich darum kümmern lassen. Ich kann dies nur empfehlen, da dadurch viel Fehlerpotential in diesem Bereich beseitigt wird, wie z.
Die Anmerkungen auf dem neuesten Stand zu halten, ist einfach eine Qual und Sie sollten es nicht tun müssen, wenn es automatisch möglich ist. ng-annotate macht genau das.
Es sollte sich mit grunt-ng-annotate und gulp-ng-annotate gut in Ihren Erstellungsprozess integrieren lassen .
quelle
uglify({ output : { beautify : true }})
Oliver Salzburgs Artikel war fantastisch. Upvoted.
Tipp für alle, die diesen Fehler haben könnten. Meins wurde einfach dadurch verursacht, dass vergessen wurde, ein Array für einen Direktiven-Controller zu übergeben:
SCHLECHT
GUT
quelle
/* @ngInject */
vor der Funktion hinzufügen musste . Es scheint den komplizierten Injektionsteil zu machen, ohne jedes enthaltene Modulbenutze ng-strict-di mit ng-app
Wenn Sie Angular 1.3 verwenden, können Sie sich durch die Verwendung der ngStrictDi- Direktive mit ngApp eine Welt voller Verletzungen ersparen:
Jetzt - vor der Minimierung - wird alles, was keine Anmerkungen verwendet, Ihre Konsole in die Luft jagen und Sie können den verdammten Namen sehen, ohne durch verstümmelte Stapelspuren zu suchen.
Gemäß den Dokumenten:
Eine Einschränkung : Es wird nur festgestellt , dass Anmerkungen vorhanden sind , nicht, dass die Anmerkungen vollständig sind.
Bedeutung:
Wird nicht verstehen, dass ThingB nicht Teil der Annotation ist.
Der Tipp für diesen Tipp geht an die ng-annotate- Leute, was gegenüber dem jetzt veralteten ngMin empfohlen wird.
quelle
Um den Winkel zu minimieren, müssen Sie lediglich Ihre Deklaration in den Deklarationsmodus "Array" ändern, zum Beispiel:
Von:
Zu
Wie deklariere ich Fabrikdienstleistungen?
quelle
Ich hatte gerade das gleiche Problem und löste es, indem ich einfach ngmin (jetzt veraltet) durch ng-annotate für meine Grunz-Build-Aufgabe ersetzte.
Es scheint, dass yeoman angle ebenfalls aktualisiert wurde, um ng-annotate ab diesem Commit zu verwenden: https://github.com/yeoman/generator-angular/commit/3eea4cbeb010eeaaf797c17604b4a3ab5371eccb
Wenn Sie jedoch eine ältere Version von yeoman eckig wie ich verwenden, ersetzen Sie ng-min einfach durch ng-annotate in Ihrem package.json:
Führen Sie
npm install
(dann optionalnpm prune
) aus und folgen Sie den Änderungen im zu bearbeitenden CommitGruntfile.js
.quelle
Um zu wissen, wie der ursprüngliche Variablenname lautete, können Sie ändern, wie uglify die Variablen entstellt:
und jetzt ist der Fehler viel offensichtlicher
BEARBEITEN
So offensichtlich jetzt ...
Jetzt wird jede Variable auf einen eindeutigen Wert entstellt, der auch das Original enthält. Öffnen Sie einfach das minimierte Javascript und suchen Sie nach "a_orig_ $ stateProvider_91212" oder was auch immer ... Sie werden es in seinem ursprünglichen Kontext sehen ...
könnte nicht einfacher sein ...
quelle
Vergessen Sie auch nicht die
resolve
Eigenschaft der Route. Es muss auch als Array definiert werden:quelle
Mit Generator-Schluck-Winkel:
Schreiben Sie / ** @ngInject * / vor jeden Controller, Dienst, jede Anweisung.
quelle
Eine schnelle und schmutzige Lösung für dieses Problem, wenn Sie nicht benötigen, dass Uglify Ihre Variablennamen entstellt / verkürzt, besteht darin, mangle = false in Ihrer Grunt-Datei festzulegen
quelle