Отладка неизвестного поставщика в минимизированном угловом 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.
У меня тоже была похожая проблема. Решением является точный ответ из пункта 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