如何修复角度缩小生成后的注入器错误

How to fix injector error after Angular minification build?

本文关键字:注入器 错误 何修复 缩小      更新时间:2023-09-26

在发言之前,我读过关于它的文章​​建议,但仍会导致错误。查看短代码:

function IndexController($scope, $route, $routeParams, $location){
  $scope.sfv = project.version.name;
}
angular.module("TkwebMobile", ['ngRoute', 'ngCookies'])
  .controller('IndexController', ['$scope', '$route', '$routeParams', '$location', IndexController]);

只有这一点和错误仍然存在。我用grunt来表示"uglify",还用"concat"来表示"lib"中的代码。甚至我使用了Angular文档中推荐的"注入"。

Uncaught Error: [$injector:modulerr] Failed to instantiate module TkwebMobile due to:
Error: [$injector:unpr] Unknown provider: a

是不是有凹陷的问题?(grunt contrib concat)

这是由于您的缩小,特别是缩小和修改变量名的选项。

Angular根据参数的名称确定要注入函数的值。例如

angular.factory('MyFactory', function($location) {...});

将导致angular查找任何名为'$location'的依赖项,然后用传递的$location值作为其参数来调用函数。

当你缩小你的javascript,打开一个名为mangle的选项时,变量名就会被破坏。上一个函数将变成这个。。。

angular.factory('MyFactory', function(a) {...});

Angular在源代码中不再有正确的参数名称,因为$location现在是a。这节省了javascript的大小,但完全破坏了Angular的隐式依赖解析。你可以用两种方法中的一种来解决这个问题。

第一个是angular为您提供的功能。

angular.factory('MyFactory', ['$location', function(a) {...}]);

您提供数组中参数的名称,数组的最后一个元素是要将参数注入其中的函数。这样,你在代码中调用什么参数并不重要,而且minifier永远不会更改字符串文字,所以Angular总是知道你想要什么。

如果您不想失去不必使用数组表示法的便利性,另一种方法是关闭迷你图上的mangle设置。这显然意味着你不会缩小到同样的程度,但要问问自己,这些额外的字节是否真的值得。

中途之家是使用类似ngMin的东西,允许在代码中注释数组符号,然后继续缩小。这是世界上最好的imo,但增加了部署客户端js的复杂性。

编辑

关闭咕哝声中的混乱行为的正确设置是。。。

uglify: {
  options: {
    report: 'min',
    mangle: false
  }
}

但是ngAnnotate包可以避免这种情况。请参阅此处了解更多信息。(ngAnnotate是接管ngMin的软件包)

我也遇到过类似的问题。事实证明,我没有正确识别和格式化控制器和服务等的依赖项。我相信我是通过查看缩小输出发现这一点的。(让我告诉你,这很艰难。)

基本上,我必须查看所有文件,并验证依赖项列表是否与我在控制器和服务中使用的内容相匹配。这很奇怪,因为它在没有变化的情况下工作。

下面是我必须做的一个例子:

原件:

angular.module('FootCtrl', []).controller('FooterController', function($scope) {
    $scope.footer = 'Copyright 'u00A9 ' + new Date().getFullYear() + name;
});

已修复

angular.module('FootCtrl', []).controller('FooterController', ["$scope", function($scope) {
    $scope.footer = 'Copyright 'u00A9 ' + new Date().getFullYear() + name;
}]);

也许要注意我使用单引号和双引号的地方。

希望这能有所帮助。我不确定你是否有比显示的更多的代码——如果没有,我也不太确定。

我遇到了这个问题,我花了很多时间才弄清楚问题是什么,因为我尝试禁用变量名称的篡改,使用$inject数组,而不是在依赖角度隐式依赖注入的同时将服务和提供程序名称传给函数定义,但问题仍然存在。事实证明,在我的一个使用IIFE的控制器中,末尾缺少分号。查看下面的代码。

之前:

(函数(){

})()

由于自动插入分号,上面的代码在缩小之前可以正常工作,但在缩小之后由于没有分号而中断。因此,经过修正后,它看起来如下。

正确:

(函数(){

})();

这解决了我的问题。我希望这能帮助到一些人注意:我使用grunt useminPrepare、usemin、copy、uglify和ngAnnotate。