【问题标题】:Debugging Unknown provider in minified angular javascript在缩小的 Angular javascript 中调试未知提供程序
【发布时间】:2014-05-05 19:49:31
【问题描述】:

我很难确定在我的 Angular 应用程序中有哪些方法会导致错误:

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

只有在 ASP.Net 捆绑和缩小 javascript 后才会发生这种情况。

我已确保所有控制器和任何其他 DI 都使用缩小安全方法,即我的控制器/服务等使用该方法:

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

我已经检查了我们应用程序中的每个 JS 文件 - 有很多......并且找不到任何违反这种注入依赖项的方式的东西 - 尽管一定有一个地方......

有没有更好的方法来查明可能导致此错误的方法?

谢谢

【问题讨论】:

  • 我的猜测是缩小器正在更改函数的参数名称。由于 DI 项是通过字符串注册的(未通过缩小修改),因此它们将不再匹配,因此 DI 失败。
  • 是的,情况就是这样,尽管我的所有(我可以看到的)DI 都是使用安全的方式完成的。就是找不到那个不...
  • 虽然不是解决办法;您可以包含非缩小版本的 Angular + 缩小自定义代码。这将允许您在报告的错误上设置断点并从那里回溯它(通过将奇怪的命名函数与您自己的函数进行逻辑比较)。
  • @MarvinSmit - 这就是我目前正在做的事情 - 我美化了我缩小的 JS 并试图追踪 - 几乎不可能(到目前为止)
  • 我发现了我们的问题.. 我们有一个第 3 方指令 - github.com/durated/angular-scroll - 没有一个 DI 方法被编写为安全的缩小。调整它们,现在一切都很好。

标签: javascript angularjs


【解决方案1】:

对于其他在这个问题上苦苦挣扎的人,我找到了一个更简单的解决方案。如果你打开你的开发者控制台(在 chrome 上)并在 angular 抛出错误的地方添加一个断点:

然后,在右侧的堆栈跟踪中,单击您看到的第一个“调用”。这将带您进入调用函数,其中第一个参数是 angular 尝试注入的函数:

然后我在我的代码中搜索了一个看起来像那个函数的函数(在本例中为 grep "\.onload" -R public),并找到了 8 个要检查的地方。

我希望这会有所帮助!

【讨论】:

  • 这应该是答案!考虑到我们在哪里犯了错误,这节省了我在代码库中搜索的时间,这将是徒劳的。非常感谢!
  • 您的示例在未缩小的 javascript 中添加了断点。 OP 在缩小 js 时遇到问题。如果错误仅在缩小后出现,这将如何解决问题?
  • @glyph 我刚刚更改了我的构建过程,所以 angular.js 没有被缩小,所有其他的仍然是,能够做到这一点。
  • 这应该是公认的答案。而且它变得更好:当您将鼠标悬停在fn 上,并看到带有该功能的弹出窗口时,您可以单击该功能,您将被直接带到相关功能。 (不要忘记使用 Chome 自动格式化您的缩小代码以获得更好的概览!)
  • 要将此策略与缩小的 angular.js 一起使用,请在调用堆栈中搜索 $get,这将带您调用调用方法。
【解决方案2】:

对于阅读本文的任何人,使用 Angular 1.3

您现在可以像这样使用 Angular 的 ng-strict-di 检查:

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

如果您没有使用数组语法加载依赖项,这将为您提供适当的错误消息。

【讨论】:

  • 如果你手动引导应用程序而不是在 html 中使用 ng-app,你知道你会这样做吗?
  • 嗯不知道,也许检查一下ngStrictDi的文档,也许你可以以某种方式注入并加载它?
  • @Neil 您可以在引导函数{ strictDi: true } 的选项参数中传递它,如标题使用严格依赖注入下的here 所述
  • 这应该是这个问题的正确答案。它工作得很好,节省了我很多时间查看代码。
  • docs.angularjs.org/error/$injector/strictdi?p0=controller 错误消息没有我预期的那么明确:它没有告诉哪个控制器有故障。 :-/ 基本上,它只确认我们在缩小模式下会遇到麻烦...
【解决方案3】:

我遇到了同样的问题,但我找到了一个可能对其余问题有所帮助的解决方案。我的建议基本上是我在 cmets 和 docs 中看到的。如果你使用的是 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 中,所以我唯一需要做的就是在最后添加这个小代码:

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

Angular Docs 中有更好的记录

我希望这会有所帮助。祝你好运!

【讨论】:

    【解决方案4】:

    如 cmets 中所述,这些是我尝试查找 JS 错误的步骤。

    如果有其他更简单的解决方案,请随时发布,我可能会将其标记为已接受。


    尝试调试缩小的代码是一场噩梦。

    我最终所做的是直接从 Chrome 中的检查器复制我的缩小 javascript。

    然后我将 JS 粘贴到 http://www.jspretty.com/ - 我曾尝试过 http://jsbeautifier.org/,但发现他们的网站被如此大的 JS 代码冻结。

    一旦它“相当完善”,我就在我的解决方案中创建了一个 test.js 文件,并将现在更易于阅读的代码粘贴到其中。

    快速注释掉我的_layout 中的@script 标记并添加指向test.js 文件的链接,我准备调试现在更容易阅读的Javascript 块。

    遍历调用堆栈仍然很尴尬,尽管现在您可以看到实际的方法,这使得它变得更加不可能。

    【讨论】:

    • 也许这个问题很少见,但你为我节省了几个小时的时间。非常感谢。
    【解决方案5】:

    帮助我解决这个问题的东西(终于!)实际上已经在 Angular 文档中了!如果在定义ng-app 的任何位置将ng-strict-di 属性添加到代码中,angular 将发出严格警告,以便您可以更轻松地查看开发模式下发生的情况。我希望这是默认设置!

    请参阅 ngApp 文档底部的参数列表。

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

    【讨论】:

    • 在给出自己的答案之前检查以前的答案可能很有用... :-)
    【解决方案6】:

    这对我有用的方式如下:

    1) 有两个最小化和普通的测试规范 html 文件(单元测​​试)

    2) 确保文件的捆绑顺序与普通规范文件的顺序相同(JS 脚本参考)

    3) 确保显式声明所有依赖项(数组或 $inject 声明参见http://www.ozkary.com/2015/11/angularjs-minimized-file-unknown-provider.html

    当单元测试(最小化引用)文件出现错误时,我可以比较并确保文件的引用与工作文件的顺序正确。

    希望有所帮助。

    【讨论】:

      【解决方案7】:

      我遇到了类似的问题,花了很多时间进行调查,发现是 Chrome 扩展程序 Batarang 注入了错误代码,Angular 中的错误看起来完全一样。真的很遗憾,很难找到究竟是什么导致了这个问题。

      【讨论】:

        【解决方案8】:

        我也有类似的问题。解决方案正是 ozkary 第 3 点的答案,即确保明确声明所有依赖项,包括路线的“解决”部分。

        下面是我的代码。

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

        【讨论】:

          【解决方案9】:

          对于那些正在引导他们的 angularjs 应用程序的人。

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

          不要忘记在非缩小代码中进行调试,您应该能够很快找出格式错误的依赖注入。

          格式错误的注入通常是这样格式化的:

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

          但应该看起来更像这样

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

          这是在 angularjs 1.7.2 中测试的

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多