Angular.module缩小错误

有最难的时候试图找出为什么缩小不起作用。

我已经通过一个数组对象注入我的提供者之前,通过networking众多的build议function,但仍然“未知的提供者:aProvider < – 一个”

定期:

var app = angular.module('bpwApp', ['ui.bootstrap', 'ui', 'myTabs']) .config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){ $routeProvider. when('/', {templateUrl: 'partials/home.jade', controller: HomeCtrl}); $locationProvider.html5Mode(true); }]) 

精缩:

 var app = angular.module('bpwApp', ['ui.bootstrap', 'ui', 'myTabs']) .config(['$routeProvider', '$locationProvider', function(a, b){ a. when('/', {templateUrl: 'partials/home.jade', controller: HomeCtrl}); b.html5Mode(true); }]) 

任何build议将非常有用!

我之前用Grunt.js Uglify插件遇到过这个问题。

其中一个选项是mangle

 uglify: { options: { mangle: false }, 

我相信在“像string”运行正则expression式function,并将其微型化。

例如:

 angular.module("imgur", ["imgur.global","imgur.album"]); 

会成为:

 angular.module("a", ["a.global","a.album"]); 

禁用它—这个function对Angular来说并不好用。

编辑:

更准确地说,@JoshDavidMiller解释说:

Uglify mangle只能像variables一样崩溃,这实际上是导致AngularJS问题的原因。 也就是说,问题在于注入而不是定义。

function MyCtrl($scope, myService)会被调整为function MyCtrl(a, b) ,但是一个string中的服务定义不应该被修改。

  • 在运行uglify之前运行ng-min解决了这个问题。

问题

从AngularJS:糟糕的部分 :

Angular有一个内置的dependency injection器,可以根据参数的名称将适当的对象传递给你的函数:

 function MyController($scope, $window) { // ... } 

在这里,参数$scope$window的名字将与已知名字的列表进行匹配,相应的对象被实例化并传递给函数。 Angular通过调用函数的toString()获取参数名称,然后parsing函数定义。

这个问题当然是在你缩小代码的时候停止工作 。 由于您关心用户体验,因此您将会缩小您的代码,因此使用此DI机制将会破坏您的应用程序。 实际上,一种常见的开发方法是在开发中使用unminified代码以便于debugging,然后在推向生产或分期时缩减代码。 在这种情况下,这个问题不会在它受到最大伤害的时候变成丑陋的头脑。

(……)

由于这种dependency injection机制在一般情况下并不实际工作,所以Angular也提供了一种机制。 可以肯定的是,它提供了两个。 你可以像这样传递一个数组:

 module.controller('MyController', ['$scope', '$window', MyController]); 

或者你可以在你的构造函数中设置$inject属性:

 MyController.$inject = ['$scope', '$window']; 

您可以使用ng-annotate来自动添加缩小所需的注释:

ng-annotate添加和删​​除AngularJSdependency injection注释。 这是非侵入性的,所以你的源代码保持完全相同,否则。 没有失去意见或移动线路。

ng-annotatengmin (现在已经被弃用)更快,更稳定,并且它有很多工具的插件:

  • grunt-ng-annotate
  • gulp-ng-annotate
  • browserify-annotate

从AngularJS 1.3开始,在ngApp还有一个名为ngStrictDi的新参数:

如果该属性出现在应用程序元素上,则将以“严格-di”模式创build注入器。 这意味着应用程序将无法调用不使用显式函数注释的函数(因此不适合缩小),如dependency injection指南中所述 ,有用的debugging信息将有助于追踪这些错误的根源。

我有同样的错误。 但是,对我来说,问题是指令的控制器声明。 你应该这样做。

 myModule.directive('directiveName', function factory(injectables) { var directiveDefinitionObject = { templateUrl: 'directive.html', replace: false, restrict: 'A', controller: ["$scope", "$element", "$attrs", "$transclude", "otherInjectables", function($scope, $element, $attrs, $transclude, otherInjectables) { ... }] }; return directiveDefinitionObject; }); 

https://github.com/angular/angular.js/pull/3125

我有一个类似的问题,使用grunt,ngmin和uglify。

我按这个顺序运行进程:concat,ngmin,uglify

我继续从angular度得到$注入器错误,直到我添加了uglify选项mangle:false – 那么一切都是固定的。

我也尝试添加这样的例外uglify:

  options: { mangle: { except: ['jQuery', 'angular'] } } 

但无济于事…

这里是我的gruntFile.js进一步的澄清:

 module.exports = function(grunt) { 'use strict'; // Configuration goes here grunt.initConfig({ pkg: require('./package.json'), watch: { files: ['scripts/**/*.js', 'test/**/*spec.js', 'GruntFile.js'], tasks: ['test', 'ngmin'] }, jasmine : { // Your project's source files src : ['bower_components/angular/angular.js', 'bower_components/angular-mocks/angular-mocks.js', 'scripts/app.js', 'scripts/**/*.js' ], // Your Jasmine spec files options : { specs : 'test/**/*spec.js', helpers: 'test/lib/*.js' } }, concat: { dist : { src: ['scripts/app.js', 'scripts/**/*.js'], dest: 'production/js/concat.js' } }, ngmin: { angular: { src : ['production/js/concat.js'], dest : 'production/js/ngmin.js' } }, uglify : { options: { report: 'min', mangle: false }, my_target : { files : { 'production/app/app.min.js' : ['production/js/ngmin.js'] } } }, docular : { groups: [], showDocularDocs: false, showAngularDocs: false } }); // Load plugins here grunt.loadNpmTasks('grunt-ngmin'); grunt.loadNpmTasks('grunt-docular'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jasmine'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-connect'); // Define your tasks here grunt.registerTask('test', ['jasmine']); grunt.registerTask('build', ['concat', 'ngmin', 'uglify']); grunt.registerTask('default', ['test', 'build', 'watch']); 

};

AndrewM96 ng-minbuild议是对的。

alignment和空白对Uglify和Angular都很重要。

Uglify有一个选项来禁用特定文件的修改:

 options: { mangle: { except: ['jQuery', 'angular'] } } 

https://github.com/gruntjs/grunt-contrib-uglify#reserved-identifiers

这是很难debugging的,因为很多服务被命名为相同的(主要是e或a)。 这不会解决错误,但会为您提供未解决服务的名称 ,使您能够在错误的输出中跟踪代码中的位置,并最终使您解决问题:

进入lib/scope.jslib/scope.jsnode_modules/grunt-contrib-uglify/node_modules/uglify-js/lib/scope.js )并replace该行

 this.mangled_name = this.scope.next_mangled(options); 

 this.mangled_name = this.name + "__debugging_" + counter++ 

我有一个类似的问题。 并以下面的方式解决它。 在运行uglify之前,我们需要运行一个名为gulp-ng-annotate的Gulp模块。 所以我们安装这个模块

 npm install gulp-ng-annotate --save-dev 

然后在Gulpfile.js中执行require

 ngannotate = require('gulp-ng-annotate') 

并在你的usemin任务做这样的事情

 js: [ngannotate(), uglify(),rev()] 

这为我解决了。

[编辑:修正错别字]