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-annotate
比ngmin
(现在已经被弃用)更快,更稳定,并且它有很多工具的插件:
-
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; });
我有一个类似的问题,使用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-min
build议是对的。
alignment和空白对Uglify和Angular都很重要。
Uglify有一个选项来禁用特定文件的修改:
options: { mangle: { except: ['jQuery', 'angular'] } }
https://github.com/gruntjs/grunt-contrib-uglify#reserved-identifiers
这是很难debugging的,因为很多服务被命名为相同的(主要是e或a)。 这不会解决错误,但会为您提供未解决服务的名称 ,使您能够在错误的输出中跟踪代码中的位置,并最终使您解决问题:
进入lib/scope.js
的lib/scope.js
( node_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()]
这为我解决了。
[编辑:修正错别字]