如何在角度缩小构建后修复注入器错误?

Ade*_*nes 7 javascript minify angularjs

在发言之前,我读到它提出了建议,但仍然导致错误.看看简短的代码:

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

只有这个和错误仍然存​​在.我正在使用grunt来"uglify",而且我也使用"concat"将代码统一在"lib"中.甚至我在Angular文档中使用了"注入".

Uncaught Error: [$injector:modulerr] Failed to instantiate module TkwebMobile due to:
Error: [$injector:unpr] Unknown provider: a
Run Code Online (Sandbox Code Playgroud)

这是grunt concat的问题吗?(咕噜-的contrib-的concat)

Law*_*nes 10

这是因为你的缩小,特别是选项来缩小和裂伤您的变量名.

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

angular.factory('MyFactory', function($location) {...});
Run Code Online (Sandbox Code Playgroud)

...将导致angular查找命名的依赖项'$location',然后使用$location作为参数传递的值调用函数.

当你缩小你的javascript时,启用了一个名为mangle的选项,那么变量名称就会被破坏.以前的功能将变成这个......

angular.factory('MyFactory', function(a) {...});
Run Code Online (Sandbox Code Playgroud)

Angular在源代码中不再具有正确的参数名称,就像$location现在一样a.这节省了javascript的大小,但完全破坏了Angular的隐式依赖解析.您可以通过以下两种方式之一解决此问题.

第一个是角度为您提供的功能.

angular.factory('MyFactory', ['$location', function(a) {...}]);
Run Code Online (Sandbox Code Playgroud)

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

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

中间的房子是使用像ngMin这样的东西,允许将数组符号注释到代码中,然后继续缩小.这是两个世界上最好的imo,但增加了部署客户端js的复杂性.

编辑

关闭grunt中的mangle行为的正确设置是......

uglify: {
  options: {
    report: 'min',
    mangle: false
  }
}
Run Code Online (Sandbox Code Playgroud)

但ngAnnotate包可以避免这种情况.有关详细信息,请参见此处 (ngAnnotate是接管ngMin的包)