Der*_*ler 99 google-chrome uglifyjs angularjs source-maps
当我加载我的AngularJS应用程序的缩小版(通过UglifyJS)时,我在控制台中收到以下错误:
Unknown provider: aProvider <- a
Run Code Online (Sandbox Code Playgroud)
现在,我意识到这是由于变量名称错误造成的.unmangled版本工作得很好.但是,我确实希望使用变量名称修改,因为它大大减少了我们的JS输出文件的大小.
出于这个原因,我们在构建过程中使用了ngmin,但它似乎并没有解决这个问题,尽管它在过去很好地帮助了我们.
因此,为了调试此问题,我在uglify grunt任务中启用了源映射.它们生成得很好,Chrome 会从服务器加载地图.然而,我仍然得到同样无益的错误信息,即使我的印象是我现在应该看到提供者的原始名称.
如何让Chrome使用源地图告诉我这里的问题是哪个提供商,或者,我怎样才能以其他方式找到提供商?
Der*_*ler 191
我仍然希望知道我怎么能找到我们的源代码,导致此问题的地方,但因为我已经能够手动查找问题.
在全局范围内声明了一个控制器函数,而不是.controller()在应用程序模块上使用调用.
所以有这样的事情:
function SomeController( $scope, i18n ) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
这对于AngularJS来说效果很好,但为了使它能够正确处理,我不得不将其更改为:
var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );
Run Code Online (Sandbox Code Playgroud)
在进一步测试之后,我实际上发现了更多控制器的实例也导致了问题.这就是我手动找到所有这些源的方法:
首先,我认为在uglify选项中启用输出美化非常重要.对于我们的grunt任务意味着:
options : {
beautify : true,
mangle : true
}
Run Code Online (Sandbox Code Playgroud)
然后,我在Chrome中打开了项目网站,DevTools打开了.这导致如下记录的错误:

我们感兴趣的呼叫追踪中的方法是我用箭头标记的方法.这是providerInjector在injector.js.您将要在它抛出异常的位置放置断点:

当您现在重新运行应用程序时,将触发断点,您可以跳转调用堆栈.将有来自invokeininjector.js的调用,可从"不正确的注入令牌"字符串中识别:

该locals参数(错位,以d我的代码)给出了一个不错的主意,哪些对象在源的问题是:

快速浏览grep我们的源代码可以找到许多实例modalInstance,但是从那里开始,很容易在源代码中找到这个位置:
var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};
Run Code Online (Sandbox Code Playgroud)
必须更改为:
var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];
Run Code Online (Sandbox Code Playgroud)
如果变量没有保存有用的信息,你也可以进一步向上跳转,你应该打一个invoke应该有其他提示的调用:

既然你有希望找到问题,我觉得我应该提一下如何在将来再次发生这种情况.
显然,您可以在任何地方使用内联数组注释,或者(取决于您的偏好)$inject属性注释,并且尽量不要在将来忘记它.如果这样做,请确保启用严格依赖注入模式,以尽早捕获这样的错误.
小心!如果您正在使用Angular Batarang,StrictDI可能不适合您,因为Angular Batarang会将未经注释的代码注入您的内容(糟糕的Batarang!).
或者你可以让ng-annotate来处理它.我强烈建议这样做,因为它消除了很多这方面的错误,例如:
保持注释是最新的只是一个痛苦的屁股,你不应该这样做,如果它可以自动完成.ng-annotate正是如此.
它应该与grunt-ng-annotate和gulp-ng-annotate很好地集成到你的构建过程中.
Ash*_*rke 30
奥利弗·萨尔茨堡的写作太棒了.Upvoted.
提示可能有此错误的任何人.我只是因为忘记为指令控制器传入数组而导致:
return {
restrict: "E",
scope: {
},
controller: ExampleDirectiveController,
templateUrl: "template/url/here.html"
};
Run Code Online (Sandbox Code Playgroud)
return {
restrict: "E",
scope: {
},
controller: ["$scope", ExampleDirectiveController],
templateUrl: "template/url/here.html"
};
Run Code Online (Sandbox Code Playgroud)
Mar*_*Fox 25
如果你正在使用Angular 1.3,那么通过在ngApp中使用ngStrictDi指令可以为自己节省一个伤害的世界:
<html lang="en" ng-app="myUglifiablyGreatApp" ng-strict-di>
Run Code Online (Sandbox Code Playgroud)
现在 - 预先缩小 - 任何不使用注释的东西都会炸毁你的控制台,你可以看到friggin的名字,而不需要查看损坏的堆栈跟踪.
根据文档:
应用程序将无法调用不使用显式函数注释的函数(因此不适合缩小)
有一点需要注意,它只能检测到有有注解,而不是注释是完整的.
含义:
['ThingOne', function(ThingA, ThingB) { … }]
Run Code Online (Sandbox Code Playgroud)
不会发现ThingB不是注释的一部分.
这个提示的功劳归于ng-annotate人,推荐使用现已弃用的ngMin.
Dal*_*rzo 11
要缩小角度,您需要做的就是将声明更改为"数组"声明"模式",例如:
从:
var demoApp= angular.module('demoApp', []);
demoApp.controller(function demoCtrl($scope) {
} );
Run Code Online (Sandbox Code Playgroud)
至
var demoApp= angular.module('demoApp', []);
demoApp.controller(["$scope",function demoCtrl($scope) {
}]);
Run Code Online (Sandbox Code Playgroud)
如何申报工厂服务?
demoApp.factory('demoFactory', ['$q', '$http', function ($q, $http) {
return {
//some object
};
}]);
Run Code Online (Sandbox Code Playgroud)
小智 8
我只是遇到了同样的问题并通过简单地用ng-annotate替换ngmin(现已弃用)来解决它我的grunt构建任务.
似乎yeoman angular也已更新为使用ng-annotate作为此提交:https://github.com/yeoman/generator-angular/commit/3eea4cbeb010eeaaf797c17604b4a3ab5371eccb
但是如果你像我一样使用较旧版本的yeoman角度,只需在你的package.json中用ng-annotate替换ng-min:
- "grunt-ngmin": "^0.0.3",
+ "grunt-ng-annotate": "^0.3.0",
Run Code Online (Sandbox Code Playgroud)
运行npm install(然后可选npm prune),并按照提交中的更改进行编辑Gruntfile.js.
为了知道原始变量名称是什么,您可以更改uglify如何修改变量:
../node_modules/grunt-contrib-uglify/node_modulesuglify-js/lib/scope.js
SymbolDef.prototype = {
unmangleable: [...],
mangle: function(options) {
[...]
this.mangled_name = s.next_mangled(options, this)+"_orig_"+this.orig[0].name;
[...]
}
};
Run Code Online (Sandbox Code Playgroud)
现在错误更明显了
Error: [$injector:unpr] Unknown provider: a_orig_$stateProvider
http://errors.angularjs.org/1.3.7/$injector/unpr?p0=a_orig_%24stateProvider
at eval (eval at <anonymous> (http://example.com/:64:17), <anonymous>:3155:20)
Run Code Online (Sandbox Code Playgroud)
现在很明显......
Gruntfile.js
uglify: {
example: {
options: {
beautify: true,
mangle: true
},
[...]
},
[...]
}
Run Code Online (Sandbox Code Playgroud)
../node_modules/grunt-contrib-uglify/node_modulesuglify-js/lib/scope.js
var numberOfVariables = 1;
SymbolDef.prototype = {
unmangleable: [...],
mangle: function(options) {
[...]
this.mangled_name = s.next_mangled(options, this)+"_orig_"+this.orig[0].name+"_"+numberOfVariables++;
[...]
}
};
Run Code Online (Sandbox Code Playgroud)
现在每个变量都被修改为一个唯一的值,它也包含原始...只需打开缩小的javascript并搜索"a_orig_ $ stateProvider_91212"或者其他......你会在它的原始上下文中看到它...
再也不容易了......
| 归档时间: |
|
| 查看次数: |
40067 次 |
| 最近记录: |