Angular ошибка модификации модуля.

Имея самое страшное время, пытаясь понять, почему минимизация не работает.

Я ввел через объект массива мои провайдеры перед этой функцией в многочисленных предложениях по сети и все же "Неизвестный поставщик: 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);
    }])

Minified:

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

Любое предложение было бы очень обязательным!

Ответ 1

Предложение AndrewM96 ng-min верное.

Выравнивание и пробел имеют значение Uglify, а также Angular.

Ответ 2

Я столкнулся с этой проблемой, прежде чем использовать плагин Grunt.js Uglify.

Один из вариантов: mangle

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 решает эту проблему.

Ответ 3

Проблема

Из AngularJS: Плохие части:

Angular имеет встроенный инжектор зависимостей, который пройдет соответствующий объекты к вашей функции, основанные на именах ее параметров:

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

Здесь имена параметров $scope и $window будут сопоставляется с списком известных имен, а соответствующие объекты получаются экземпляр и передается функции. Angular получает параметр имена, вызвав toString() в функции, а затем разобрав определение функции.

Проблема с этим, конечно, в том, что она перестает работать момент, когда вы уменьшите свой код. Поскольку вы заботитесь о работе с пользователем вы будете минимизировать свой код, таким образом, используя этот механизм DI сломайте приложение. Фактически, общей методологией разработки является использование unminified code в разработке, чтобы облегчить отладку, а затем минимизировать код при нажатии на производство или постановку. В этом случае это проблема не заставит его уродливую голову, пока вы не достигнете того места, где она болит больше всего.

(...)

Поскольку этот механизм инъекции зависимостей фактически не работает в общий случай, Angular также обеспечивает механизм, который делает. Быть уверенным, он обеспечивает два. Вы можете либо пройти по массиву так:

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

Или вы можете установить свойство $inject в свой конструктор:

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

Решение

Вы можете использовать ng-annotate для автоматического добавления аннотаций, необходимых для минимизации:

ng-annotate добавляет и удаляет инъекцию зависимостей AngularJS аннотаций. Это неинтрузивно, поэтому исходный код остается в точности то же самое. Нет потерянных комментариев или перемещенных строк.

ng-annotate быстрее и стабильнее, чем ngmin (который теперь устарел), и у него есть плагины для многих инструментов:


Начиная с AngularJS 1.3, в ngApp появился новый параметр ngStrictDi:

если этот атрибут присутствует в элементе приложения, инжектор будет созданный в режиме "строго-ди". Это означает, что приложение не удастся для вызова функций, которые не используют явную аннотацию функции (и поэтому непригодны для минимизации), как описано в Зависимость Руководство по вводу в эксплуатацию, а также полезная информация об отладке поможет отслеживать в корне этих ошибок.

Ответ 4

У меня такая же ошибка. Однако для меня проблема заключается в декларации контроллера директив. Вы должны сделать это вместо этого.

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

Ответ 5

У меня была аналогичная проблема с использованием grunt, ngmin и uglify.

Я выполнил этот процесс в следующем порядке: concat, ngmin, uglify

Я продолжал получать ошибку инжектора $с angular, пока я не добавил в опции uglify options 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 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']);

};

Ответ 7

Это очень сложно отлаживать, потому что многие службы называются одинаковыми (в основном, e или a). Это не решит ошибку, но предоставит вам имя неразрешенной службы, которая позволит вам отслеживать в укр. Выводе местоположение в коде и, наконец, позволяет решить проблему

Перейдите в lib/scope.js из Uglify2 (node_modules/grunt-contrib-uglify/node_modules/uglify-js/lib/scope.js) и замените строку

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

с

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

Ответ 8

У меня была аналогичная проблема. И решил это следующим образом. Нам нужно запустить модуль Gulp под названием gulp -ng-annotate перед запуском uglify. Поэтому мы устанавливаем этот модуль

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

Затем выполните требование в Gulpfile.js

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

И в вашей задаче usemin сделайте что-то вроде этого

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

Это решило это для меня.

[EDIT: исправлены опечатки]