Отладка неизвестного поставщика в минимизированном угловом JavaScript

Я с трудом пытаюсь определить, какие из очень многих методов, которые у меня есть в моем угловом приложении, могут вызвать ошибку:

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

Это происходит только после того, как ASP.Net объединяет и минимизирует JavaScript.

Я гарантировал, что все контроллеры и любые другие DI используют метод минимизации безопасности, IE Мои контроллеры / службы и т. Д. Используют метод:

appControllers.controller('myCtrl', ['$scope', function($scope){
        //......
}]);

Я просмотрел каждый файл JS в нашем приложении - их много... и не могу найти ничего, что нарушает этот способ введения зависимостей - хотя где-то он должен быть...

Есть ли лучший способ определить, какой метод может быть причиной этой ошибки?

Спасибо

9 ответов

Решение

Как упоминалось в комментариях, это шаги, которые я предпринял, чтобы попытаться найти ошибку JS.

Если есть другое, более простое решение, пожалуйста, опубликуйте его, и я могу пометить его как принятое.


Попытка отладить минимизированный код - это кошмар.

В конечном итоге я скопировал минимизированный javascript непосредственно от инспектора в Chrome.

Затем я вставил JS в http://www.jspretty.com/ - я пробовал http://jsbeautifier.org/ но обнаружил, что их сайт застыл с таким большим кодом JS.

Когда-то это было довольно симпатично, я создал файл test.js в своем решении и вставил в него код, который теперь легче читать.

Быстрый шаг, чтобы закомментировать @script тег в моем _layout и добавьте ссылку на файл test.js, и я был готов к отладке фрагмента Javascript, который теперь гораздо легче читать.

Просматривать стек вызовов по-прежнему довольно неловко, хотя теперь вы можете увидеть реальные методы, которые делают его гораздо менее невозможным.

Для всех, кто борется с этой проблемой, я нашел более простое решение. Если вы откроете консоль разработчика (на Chrome) и добавите точку останова, где angular выдает ошибку:

угловое бросание ошибки

Затем, на трассировке стека справа, нажмите на первый "вызов", который вы видите. Это приведет вас к функции invoke, где первый параметр - это функция, которую angular пытается внедрить:

Я был в состоянии проверить функцию

Затем я сделал поиск в моем коде функции, которая была похожа на эту (в данном случае grep "\.onload" -R public) и нашел 8 мест для проверки.

Надеюсь, это поможет!

Для тех, кто читает это, используя Angular 1.3

Теперь вы можете использовать проверку Angular ng-strict-di следующим образом:

<div ng-app="some-angular-app" ng-strict-di>
  ...
</div>

Это даст вам соответствующее сообщение об ошибке, если вы не загрузили свои зависимости, используя синтаксис массива.

У меня была такая же проблема, и я нашел решение, которое могло бы помочь остальным. То, что я предлагаю, в основном то, что я видел в комментариях и документах. Если вы используете Angular 1.3.0 или выше, вы можете использовать это:

<html ng-app="myApp" ng-strict-di>
   <body>
      I can add: {{ 1 + 2 }}.
      <script src="angular.js"></script>
    </body>
</html>

В моем случае у меня есть все в файле app.js, поэтому единственное, что мне нужно сделать, чтобы найти мои проблемы с DI, это добавить этот маленький код в конце:

angular.bootstrap(document, ['myApp'], {
  strictDi: true
});

Это лучше задокументировано в Angular Docs

Надеюсь, это поможет. Удачи!

Что-то, что помогло мне решить это (наконец-то!), Уже было в угловых документах! Если вы добавите ng-strict-di приписать свой код везде, где вы определяете ng-app, angular выдаст строгое предупреждение, чтобы вам было легче видеть, что происходит в режиме разработки. Я желаю, чтобы это было по умолчанию!

Смотрите список аргументов внизу документации ngApp.

https://docs.angularjs.org/api/ng/directive/ngApp

У меня тоже была похожая проблема. Решением является точный ответ из пункта 3 ozkary, который заключается в том, чтобы явно объявить все зависимости, включая "разрешить" часть вашего маршрута.

Ниже мой код.

when('/contact/:id', {
      controller: 'contactCtrl',
      templateUrl: 'assets/partials/contact.html',
      resolve: {
         contact: ['ContactService', '$route', function(ContactService, $route) {
            return ContactService.getContactDetail($route.current.params.id);
         }]
      }
})

Для меня это работает следующим образом:

1) иметь два HTML-файла спецификации теста (модульный тест), свернутые и простые

2) убедитесь, что пакет файлов находится в том же порядке, что и обычный файл спецификации (ссылка на скрипт JS)

3) не забудьте явно объявить все зависимости (массив или $inject объявляют, см. http://www.ozkary.com/2015/11/angularjs-minimized-file-unknown-provider.html)

Когда есть ошибка в файле модульного теста (уменьшенная ссылка), я могу сравнить и убедиться, что ссылки на файлы находятся в правильном порядке в качестве рабочего файла.

надеюсь что поможет.

У меня была похожая проблема, и я потратил много времени на изучение и выяснил, что это расширение Chrome Batarang, которое вставляет неверный код, и ошибка в Angular выглядит точно так же. Жаль, что так сложно найти, что именно является причиной проблемы.

Для тех, кто запускает приложение angularjs.

angular.bootstrap(body, ['app'], { strictDi: true });

Не забывайте отлаживать в не минимизированном коде, и вы сможете довольно быстро разобраться с внедрением некорректной зависимости.

Неправильная инъекция обычно форматируется так:

...
.run([ function(ServiceInjected){
...

Но должно выглядеть так

...
.run(['ServiceInjected', function(ServiceInjected){
...   

Это проверено в angularjs 1.7.2

Другие вопросы по тегам