Angular.module缩小bug

BPW*_*ent 81 javascript minify uglifyjs angularjs

有最艰难的时间试图弄清楚为什么缩小不起作用.

我已经通过一个数组对象注入了我的提供者之前的功能,在网络上提出了许多建议,但仍然是"未知的提供者:aProvider < - a"

定期:

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);
    }])
Run Code Online (Sandbox Code Playgroud)

精缩:

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);
    }])
Run Code Online (Sandbox Code Playgroud)

任何建议都有很大的意义!

Dan*_*nze 139

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

其中一个选择是mangle

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

我相信它会在"像字符串"上运行正则表达式函数并对它们进行微调.

例如:

angular.module("imgur", ["imgur.global","imgur.album"]);
Run Code Online (Sandbox Code Playgroud)

会成为:

angular.module("a", ["a.global","a.album"]);
Run Code Online (Sandbox Code Playgroud)

禁用它 - 此功能对Angular不起作用.

编辑:

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

Uglify mangle只会像变量一样变形,这实际上是导致AngularJS问题的原因.也就是说,问题在于注入而不是定义.

function MyCtrl($scope, myService)会被破坏function MyCtrl(a, b),但字符串内的服务定义永远不会被改变.

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

  • `mangle:true`*真的*mangle"像字符串"?我很确定它只会变形像*变量*,这实际上是导致AngularJS问题的原因.也就是说,问题在于注入而不是定义.`function MyCtrl($ scope,myService)`会被修改为`function MyCtrl(a,b)`,但是字符串里面的服务定义永远不会被改变.在运行`uglify`之前运行`ng-min`解决了这个问题,不是吗? (6认同)
  • 他更新了他的代码.他的问题不是"$ locationProvider"变成"b"或类似的东西.它只是没有用.但是,这个答案的+1 :) (3认同)

Pao*_*tti 51

问题

来自AngularJS:坏部分:

Angular有一个内置的依赖注入器,它会根据参数的名称将适当的对象传递给你的函数:

function MyController($scope, $window) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在这里,参数的名称$scope,并$window会针对已知的名单进行匹配,并相应的对象实例化,并传递给函数.Angular通过调用toString()函数获取参数名称,然后解析函数定义.

当然,问题在于它会在您缩小代码停止工作.由于您关心用户体验,因此您将缩小代码,因此使用此DI机制将破坏您的应用程序.事实上,一种常见的开发方法是在开发中使用未经编码的代码以简化调试,然后在推送到生产或暂存时缩小代码.在这种情况下,这个问题不会让你的丑陋的头脑发作,直到你最痛苦的程度.

(......)

由于这种依赖注入机制在一般情况下实际上不起作用,因此Angular也提供了一种机制.可以肯定的是,它提供了两个.您可以像这样传递一个数组:

module.controller('MyController', ['$scope', '$window', MyController]);
Run Code Online (Sandbox Code Playgroud)

或者您可以$inject在构造函数上设置属性:

MyController.$inject = ['$scope', '$window'];
Run Code Online (Sandbox Code Playgroud)

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

ng-annotate添加和删​​除AngularJS依赖注入注释.它是非侵入式的,因此您的源代码保持完全相同.没有丢失评论或移动的行.

ng-annotatengmin(现已弃用)更快更稳定,它有许多工具的插件:


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

如果app元素上存在此属性,则将以"strict-di"模式创建注入器.这意味着应用程序将无法调用不使用显式函数注释的函数(因此不适合缩小),如依赖注入指南中所述,有用的调试信息将有助于跟踪这些错误的根.


ang*_*okh 22

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

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;
  });
Run Code Online (Sandbox Code Playgroud)

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

  • 这更像是实际问题的解决方案而不是其他响应中建议的`mangle:false`,因为我们仍然希望能够破坏名称. (2认同)

Ste*_*how 9

我使用grunt,ngmin和uglify有类似的问题.

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

我继续从角度获取$ injector错误,直到我在uglify选项中添加了mangle:false - 然后一切都被修复了.

我还尝试将这些例外添加到uglify中,如下所示:

 options: {
  mangle: {
     except: ['jQuery', 'angular']
  }
}
Run Code Online (Sandbox Code Playgroud)

但无济于事......

这是我的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']);
Run Code Online (Sandbox Code Playgroud)

};


BPW*_*ent 5

AndrewM96的建议ng-min是对的.

对齐和空白对Uglify和Angular都很重要.

  • [ng-min](https://github.com/btford/ngmin#conceptual-overview)似乎只处理角度文件,因此它们对`uglify`很友好.在我们的构建过程中,我们使用两者(`uglify`之前的`ng-min`)并且仍然存在uglified js的问题. (10认同)
  • 为什么这标志着答案?(另外,AndrewM96应该是AndreM96) (4认同)