Kiedy ładuję zminimalizowaną (przez UglifyJS) wersję mojej aplikacji AngularJS, pojawia się następujący błąd w konsoli:
Unknown provider: aProvider <- a
Teraz zdaję sobie sprawę, że jest to spowodowane zniekształceniem nazw zmiennych. Wersja niemangled działa dobrze. Ja jednak nie chcą skorzystać z przekręcona nazwa zmiennej, gdyż drastycznie zmniejsza rozmiar pliku wyjściowego naszej JS.
Z tego powodu używamy ngmin w naszym procesie kompilacji, ale wydaje się, że nie rozwiązuje tego problemu, mimo że dobrze nam służył w przeszłości.
Tak więc, aby debugować ten problem, włączyłem mapy źródeł w naszym uglify gruntowym zadaniu. Są one generowane w porządku i Chrome ma załadować mapy z serwera. Mimo to nadal otrzymuję ten sam nieprzydatny komunikat o błędzie, chociaż miałem wrażenie, że powinienem teraz zobaczyć oryginalną nazwę dostawcy.
Jak sprawić, by Chrome używał map źródłowych, aby powiedzieć mi, który dostawca jest tutaj przyczyną problemu, lub alternatywnie, jak mogę znaleźć dostawcę w inny sposób?
źródło
Odpowiedzi:
Nadal chciałbym wiedzieć, jak mogłem znaleźć miejsce w naszym kodzie źródłowym, które spowodowało ten problem, ale od tego czasu udało mi się znaleźć problem ręcznie.
W zasięgu globalnym została zadeklarowana funkcja kontrolera zamiast
.controller()
wywołania modułu aplikacji.Więc było coś takiego:
Działa to dobrze dla AngularJS, ale aby działało dobrze z zniekształceniem, musiałem to zmienić na:
Po dalszych testach faktycznie znalazłem wystąpienia większej liczby kontrolerów, które również powodowały problemy. Oto jak ręcznie znalazłem źródło ich wszystkich :
Przede wszystkim uważam za dość ważne włączenie upiększania produkcji w opcjach uglify. W przypadku naszego podstawowego zadania oznaczało to:
Następnie otworzyłem witrynę projektu w przeglądarce Chrome z otwartymi narzędziami DevTools. Co powoduje rejestrowanie błędu takiego jak ten poniżej:
Metoda w śledzeniu wywołań, która nas interesuje, to ta, którą zaznaczyłem strzałką. To jest
providerInjector
winjector.js
. Będziesz chciał umieścić punkt przerwania, w którym zgłosi wyjątek:Kiedy teraz ponownie uruchomisz aplikację, punkt przerwania zostanie osiągnięty i możesz przeskoczyć w górę stosu wywołań. Pojawi się wywołanie z
invoke
ininjector.js
, które można rozpoznać po ciągu „Nieprawidłowy token wstrzyknięcia”:locals
Parametr (zniekształcone, abyd
w moim kodu) daje całkiem dobry pomysł, o który obiekt w źródle jest problem:Szybkie przeglądanie
grep
naszego źródła znajduje wiele przykładówmodalInstance
, ale stamtąd łatwo było znaleźć to miejsce w źródle:Które należy zmienić na:
W przypadku, gdy zmienna nie zawiera przydatnych informacji, możesz również wskoczyć dalej na stos i powinieneś trafić call, do
invoke
którego powinno mieć dodatkowe podpowiedzi:Zapobiegaj ponownemu wystąpieniu tego zdarzenia
Teraz, gdy masz nadzieję, że znalazłeś problem, czuję, że powinienem wspomnieć, jak najlepiej uniknąć powtórzenia się tego w przyszłości.
Oczywiście możesz po prostu użyć adnotacji tablicy wbudowanej wszędzie lub (w zależności od twoich preferencji)
$inject
adnotacji właściwości i po prostu spróbować nie zapomnieć o tym w przyszłości. Jeśli to zrobisz, upewnij się, że włączyłeś tryb ścisłego wstrzykiwania zależności , aby wcześnie wychwycić takie błędy.Możesz też pozwolić, by ng-annotate się tym zajął. Gorąco polecam, ponieważ usuwa wiele potencjalnych błędów w tym obszarze, takich jak:
Utrzymywanie aktualności adnotacji to po prostu wrzód na dupie i nie powinieneś tego robić, jeśli można to zrobić automatycznie. ng-annotate robi dokładnie to.
Powinien ładnie zintegrować się z procesem kompilacji za pomocą grunt-ng-annotate i gulp-ng-annotate .
źródło
uglify({ output : { beautify : true }})
Opis Olivera Salzburga był fantastyczny. Głosowano za.
Wskazówka dla każdego, kto może mieć ten błąd. Mój był po prostu spowodowany zapomnieniem o przekazaniu tablicy dla kontrolera dyrektywy:
ZŁY
DOBRY
źródło
/* @ngInject */
przed funkcją. Wydaje się, że wykonuje skomplikowaną część wtrysku bez konieczności wpisywania każdego dołączonego modułu (używam Yeoman)użyj ng-strict-di z ng-app
Jeśli używasz kątowych 1.3 można zapisać się do świata bólu za pomocą ngStrictDi dyrektywę z ngApp:
Teraz - preminifikacja - wszystko, co nie używa adnotacji, wysadzi twoją konsolę i możesz zobaczyć imię pieprzonego człowieka bez szukania zniekształconych śladów stosu.
Zgodnie z dokumentacją:
Jedno zastrzeżenie , to tylko wykryje, że tam są adnotacje, że adnotacje nie są kompletne.
Znaczenie:
Nie złapie, że ThingB nie jest częścią adnotacji.
Podziękowania za tę wskazówkę należą się osobom z adnotacjami ng , które są zalecane w stosunku do obecnie przestarzałego ngMin.
źródło
Aby zminimalizować angular wszystko, co musisz zrobić, to zmienić swoją deklarację na tryb deklaracji tablicy, na przykład:
Z:
Do
Jak zadeklarować usługi fabryczne?
źródło
Po prostu miałem ten sam problem i rozwiązałem go, po prostu zastępując ngmin (obecnie przestarzałe) przez ng-annotate dla mojego zadania kompilacji gruntów.
Wygląda na to, że yeoman angular został również zaktualizowany, aby używać ng-annotate od tego zatwierdzenia: https://github.com/yeoman/generator-angular/commit/3eea4cbeb010eeaaf797c17604b4a3ab5371eccb
Jeśli jednak używasz starszej wersji yeoman angular jak ja, po prostu zamień ng-min na ng-annotate w swoim package.json:
uruchom
npm install
(następnie opcjonalnienpm prune
) i postępuj zgodnie ze zmianami w zatwierdzeniu do edycjiGruntfile.js
.źródło
aby wiedzieć, jaka była oryginalna nazwa zmiennej, możesz zmienić sposób, w jaki zniekształcają zmienne:
a teraz błąd jest znacznie bardziej oczywisty
EDYTOWAĆ
Teraz tak oczywiste ...
teraz każda zmienna jest zniekształcana do unikalnej wartości, która zawiera również oryginał ... po prostu otwórz zminimalizowany skrypt javascript i wyszukaj „a_orig_ $ stateProvider_91212” lub cokolwiek ... zobaczysz to w oryginalnym kontekście ...
nie może być prostsze ...
źródło
Nie zapomnij również o
resolve
właściwościach trasy. Musi być również zdefiniowany jako tablica:źródło
Z generatorem-łykiem-kątowym:
Napisz / ** @ngInject * / przed każdym kontrolerem, usługą, dyrektywą.
źródło
Szybką i brudną poprawką, jeśli nie potrzebujesz Uglify do modyfikowania / skracania nazw zmiennych, jest ustawienie mangle = false w pliku Gruntfile
źródło