[javascript] Angular.module 축소 버그

최소화가 작동하지 않는 이유를 파악하기 위해 가장 시간을 투자하십시오.

나는 배열 객체를 통해 웹에서 수많은 제안에 따라 함수 이전에 내 공급자를 삽입했지만 여전히 “알 수없는 공급자 : 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);
    }])

축소 :

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);
    }])

어떤 제안이라도 많은 의무가 있습니다!



답변

Grunt.js Uglify 플러그인 으로 전에이 문제가 발생했습니다 .

옵션 중 하나는 망글입니다.

uglify: {
  options: {
    mangle: false
  },

“문자열과 같은”정규식 함수를 실행하고 축소한다고 생각합니다.

예를 들면 :

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

될 것 :

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

비활성화 —이 기능은 Angular에서 잘 작동하지 않습니다.

편집하다:

@JoshDavidMiller가 설명하는 것처럼 더 정확하게 말하면 :

Uglify mangle는 실제로 AngularJS 문제를 일으키는 변수처럼 망글을 만듭니다 . 즉, 문제는 정의가 아니라 주입에 있습니다.

function MyCtrl($scope, myService)으로 엉망이 function MyCtrl(a, b)되지만 문자열 내부의 서비스 정의는 절대 변경되지 않아야합니다.

  • 실행 ng-min하기 전에 실행 uglify하면이 문제가 해결됩니다.


답변

문제

에서 AngularJS와 : 나쁜 부품 :

Angular에는 매개 변수의 이름을 기반으로 함수에 적절한 객체를 전달하는 의존성 주입기가 내장되어 있습니다.

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

여기에서, 매개 변수의 이름 $scope과는 $window알려진 이름의 목록에 대해 일치되고, 해당 객체 인스턴스화와 함수에 전달받을. Angular는 toString()함수 를 호출 한 다음 함수 정의를 구문 분석 하여 매개 변수 이름을 가져옵니다 .

물론 이것의 문제는 코드를 축소하는 순간 작동이 중지 된다는 것 입니다. 사용자 경험에 관심이 있기 때문에 코드가 축소되므로이 DI 메커니즘을 사용하면 앱이 손상됩니다. 실제로 일반적인 개발 방법론은 디버깅을 용이하게하기 위해 개발 과정에서 최소화되지 않은 코드를 사용한 다음 프로덕션 또는 스테이징으로 푸시 할 때 코드를 최소화하는 것입니다. 이 경우,이 문제는 가장 고통스러운 지점에 도달 할 때까지 추악한 머리를 기울이지 않습니다.

(…)

이 의존성 주입 메커니즘은 일반적인 경우에 실제로 작동하지 않기 때문에 Angular는 작동하는 메커니즘도 제공합니다. 확실히 두 가지를 제공합니다. 다음과 같이 배열을 전달할 수 있습니다.

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

또는 $inject생성자 에서 속성을 설정할 수 있습니다 .

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

해결책

ng-annotate축소에 필요한 자동 추가 주석에 사용할 수 있습니다 .

ng-annotateAngularJS 종속성 주입 주석을 추가하고 제거합니다. 방해가되지 않으므로 소스 코드는 그렇지 않으면 정확히 동일하게 유지됩니다. 잃어버린 주석이나 이동 된 줄이 없습니다.

ng-annotatengmin(현재 사용되지 않음) 보다 빠르고 안정적이며 많은 도구에 대한 플러그인이 있습니다.


AngularJS와 1.3에서 시작하면 새로운 PARAM있다 ngApp라고 ngStrictDi:

이 속성이 app 요소에있는 경우 인젝터는 “strict-di”모드로 생성됩니다. 즉, 종속성 주입 가이드에 설명 된대로 애플리케이션이 명시 적 함수 주석을 사용하지 않는 (따라서 축소에 적합하지 않은) 함수를 호출하지 못하며 유용한 디버깅 정보가 이러한 버그의 원인을 추적하는 데 도움이 될 것입니다.


답변

같은 오류가 발생했습니다. 그러나 나에게 문제는 지시문의 컨트롤러 선언입니다. 대신이 작업을 수행해야합니다.

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 순서로 프로세스를 실행했습니다.

나는 uglify options mangle : false를 추가 할 때까지 각도에서 $ injector 오류를 계속 받고있었습니다. 그러면 모든 것이 수정되었습니다.

나는 또한 다음과 같이 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이 맞습니다.

정렬과 공백은 Angular뿐만 아니라 Uglify에도 중요합니다.


답변

비슷한 문제가있었습니다. 그리고 다음과 같은 방법으로 해결했습니다. uglify를 실행하기 전에 gulp-ng-annotate라는 Gulp 모듈을 실행해야합니다. 그래서 우리는 그 모듈을 설치합니다

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

그런 다음 Gulpfile.js에서 요구 사항을 수행하십시오.

ngannotate = require(‘gulp-ng-annotate’)

그리고 usemin 작업에서 다음과 같이하십시오.

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

그것은 나를 위해 그것을 해결했습니다.

[편집 : 오타 수정]


답변

Uglify에는 특정 파일에 대한 맹 글링을 비활성화하는 옵션이 있습니다.

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

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