Unknown provider: aProvider <- a
现在,我意识到这是由于变量名称。 unmangled版本工作很好。但是,我想使用变量名称调整,因为它大大减少了我们的JS输出文件的大小。
因此,我们在构建过程中使用了ngmin,但它似乎不解决这个问题,即使它在过去服务得很好。
所以,为了调试这个问题,我在我们的uglify grunt任务中启用了源映射。它们生成的很好,Chrome会从服务器加载地图。但是,我仍然得到相同的无用的错误消息,即使我的印象,我现在应该看到提供商的原始名称。
如何让Chrome使用源地图告诉我哪个提供商是这里的问题,或者,我如何以另一种方式找到提供商?
在全局范围上声明了一个控制器函数,而不是在应用程序模块上使用.controller()调用。
所以有这样的:
function SomeController( $scope,i18n ) { /* ... */ }
这对AngularJS很好,但是为了使它正常工作,我不得不改为:
var applicationModule = angular.module( "example" ); function SomeController( $scope,i18n ) { /* ... */ } applicationModule.controller( "SomeController",[ "$scope","i18n",SomeController ] );
经过进一步的测试,我实际上发现更多的控制器的实例也引起问题。这是我如何手动找到它们的源:
首先,我认为在uglify选项中启用输出美化是相当重要的。对于我们的咕噜任务,意味着:
options : { beautify : true,mangle : true }
然后我在Chrome中打开项目网站,并打开DevTools。这会导致错误,如下面的日志:
我们感兴趣的调用跟踪中的方法是我用箭头标记的方法。这是providerInjector
in injector.js
.你将要放置一个断点,它抛出一个异常:
当你现在重新运行应用程序时,断点将被命中,你可以跳上调用堆栈。将有一个从invoke
in injector.js
,从“不正确的注入令牌”字符串可识别的调用:
locals参数(在我的代码中被转换为d)给出了一个很好的想法,你的源中的哪个对象是问题:
一个快速grep我们的源发现许多实例的modalInstance,但从那里,很容易找到这个来源:
var ModalCreateEditMeetingController = function( $scope,$modalInstance ) { };
其中必须更改为:
var ModalCreateEditMeetingController = [ "$scope","$modalInstance",function( $scope,$modalInstance ) { } ];
如果变量不保存有用的信息,你也可以进一步跳上堆栈,你应该打一个调用,它应该有额外的提示:
防止这种情况再次发生
现在你已经希望找到这个问题,我觉得我应该提到如何最好地避免这种情况再次发生在未来。
显然,你可以使用inline array annotation无处不在,或者(根据你的喜好)$inject
property annotation,只是尽量不要忘记它在未来。如果这样做,请务必启用strict dependency injection mode,以尽早收到此类错误。
Watch out! In case you’re using Angular Batarang,StrictDI might not work for you,as Angular Batarang injects unannotated code into yours (bad Batarang!).
或者你可以让ng-annotate照顾它。我强烈建议这样做,因为它消除了在这方面的许多错误的潜力,如:
>缺少DI注释
> DI注释不完整
> DI注释错误的顺序
保持注释是最新的只是一个痛苦的屁股,你不应该这样做,如果它可以自动完成。 ng-annotate正是这样。
它应该很好地集成到您的构建过程与grunt-ng-annotate和gulp-ng-annotate。