【问题标题】:Finding the cause of "Unknown provider" errors查找“未知提供程序”错误的原因
【发布时间】:2014-04-07 11:28:02
【问题描述】:

我收到以下错误:

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

我知道这是由缩小过程引起的,我理解原因。但是,有没有一种简单的方法可以确定哪个文件实际上导致了问题?

【问题讨论】:

  • 最有可能出现缩小问题。您的提供商似乎已重命名为 n
  • @DavinTryon 正如我的问题所述,我已经知道原因。我正在寻找一种无需手动搜索数百个文件即可轻松识别问题文件的方法。
  • 通常错误会在压缩文件中有一个行号,您可以查看那里并找出导致问题的资源。
  • @DavinTryon 在控制台中遍历调用堆栈只是带我通过 Angular 代码。
  • +1 @DavinTryon。堆栈跟踪仅显示 Angular 本身阻塞,而不是导致问题的文件。你偶然发现了吗?

标签: angularjs minify


【解决方案1】:

Angular 1.3.x 有一个 ng-strict-di 指令,它与 ng-app 指令位于同一元素上。当依赖项没有被注释时,这个元素会导致你的应用程序抛出一个错误。虽然它仍然没有给你有问题的代码的行号,但它确实为你提供了带有参数的函数(即 function($scope, myServiceName)),希望它足够独特,你可以很快找到它代码编辑。

该指令的一个很好的概述:ng-strict-di

【讨论】:

  • 优秀!在花了几个小时试图使用替代方法找到问题之后,这对我有用。原来我的打字稿静态 $inject 缺少'$'。
  • 对不起,我不明白你是怎么使用它的?我遇到了同样的问题,自从我开始调查为什么会发生这种情况以来已经有几个小时了!
【解决方案2】:

我理解这个问题,我有一个答案,只是稍微有点复杂。

我发现问题的方法是重命名所有标识符以使它们全部唯一,然后你会在编译的 javascript 中找到有用的东西,希望能将你指向罪魁祸首。

下载我修改后的uglify(拉取请求待定...)

brew install node 如果您没有安装节点。

./bin/uglifyjs --unique_ids original.min.js &gt;new.min.js

现在用 new.min.js 替换你编译的 js 并加载你的应用来重现问题 现在你应该得到一个依赖注入错误,比如 n4536

如果你的编辑器非常棒,你可以加载 new.min.js,查找 n4536,希望这能帮助你找出罪魁祸首。

如果不是,这将有助于打印有关该问题的一些上下文。 egrep -o '.{199}n4536.{99}' new.min.js

【讨论】:

  • 申请the fix时,此解决方案有效
  • 感谢 Oleksandr!我想我在某处忘记了提交/推送。
  • 难道你不能将每个参数“重命名”为相同的东西加上一些独特的位吗?例如,“myProvider”变为“myProvider_12345”而不是“e”。会更容易追踪问题。
  • @MindJuice 这正是我对 uglify 所做的更改。
  • 也许我理解错了,但在我看来,您的新名称并没有包含原名称中的任何内容,只是一个字母和一个数字,但我还没有真正尝试过您的更改。跨度>
【解决方案3】:

虽然如果您不知道去哪里看,似乎没有什么好方法可以调试这些 DI 问题,但我有一种感觉,我的位置不太明显……它是:

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

需要:

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

【讨论】:

  • 和我的 $httpProvider.interceptors.push(['$q',function($q) { ,我花了 5 个小时的时间,因为我只看控制器、指令和过滤器
【解决方案4】:

Angular 的注入器有 3 种方式为您解决依赖关系:

1.从函数参数名称推断依赖关系。这在所有 Angular 的示例中最常用,例如

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

在这种情况下,注入器将函数转换为字符串,解析参数名称并查找与该名称匹配的服务/工厂/其他任何东西。

2。内联注释。您可能还会遇到这种语法:

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

在这种情况下,您可以使注入器更容易,因为您明确声明了所需依赖项的名称。名称用引号括起来,js 缩小器不会修改代码中的字符串。

3.内联注释作为属性。如果您将控制器定义为函数,则可以在特殊属性$inject 中设置注释:

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

在这种情况下,我们还明确声明了依赖关系。

我的猜测是您使用的解决方案没有。 1. 一旦 minifier 改变了你隐式定义的依赖的名字,注入器就不再知道你的函数的依赖是什么。为了克服这个问题,您应该使用第 2 或第 3 种方式来注释依赖关系。

【讨论】:

  • 请重新阅读我的问题。我在问如何跟踪错误的来源。
  • @Package 我真的很喜欢这个答案,因为它很好地描述了这个概念,可以让应用程序解决其他问题。
  • 然而,它并没有回答如何追踪源头的问题。
猜你喜欢
  • 2015-03-28
  • 2013-07-07
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多