Angular.module мінування помилка

Маючи найдрібніший час, намагаючись з'ясувати, чому мініфікація не працює.

I have injected via an array object my providers prior the function per numerous suggestions across the web and yet still "Unknown provider: 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);
    }])

Будь-яка пропозиція буде дуже зобов'язана!

80
Гаразд, добре, який інтернет-мініфіка ви використовували? Це чудово працює з вашим кодом: marijnhaverbeke.nl/uglifyjs
додано Автор AndreM96, джерело
Крім того, не існує відсутнього ] ? (до закриття ) )
додано Автор AndreM96, джерело
Що ви використовуєте для зменшення коду? uglifyJS? Також перевірте: github.com/btford/ngmin ;)
додано Автор AndreM96, джерело
[Використання uglify і зменшити разом] [1] [1]: stackoverflow.com/a/24215002/2371560
додано Автор ssoward, джерело
додано Автор BPWDevelopment, джерело
Він кодує кодик. Це те, що я використовував. Питання, коли він запускається, говорить, що він не написаний належним чином і не може знайти постачальника "a"
додано Автор BPWDevelopment, джерело
Був, я забув їх у цьому конкретному фрагменті. Це не змінює факту "невідомого провайдера", як і раніше буває :(
додано Автор BPWDevelopment, джерело
Я використав ngmin, все, що він зробив, вирівняли код в іншому просторі формату. Я намагався використовувати express-uglify як проміжне програмне забезпечення, але він не працював, тому я намагався вручну використовувати онлайн-uglifier. Так чи інакше код став таким же.
додано Автор BPWDevelopment, джерело

8 Відповіді

Я поставив цю проблему перед тим, як з плагіном Grunt.js Uglify .

One of the options are

mangle

uglify: {
  options: {
    mangle: false
  },

Я, на мою думку, виконує функції регулярних викликів на "подібних ланцюжках" і мінімізує їх.

Наприклад:

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

Стане:

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

Відключити - ця функція не чудово грає з кутом.

Редагувати:

Точніше, як пояснює @JoshDavidMiller:

Uglify mangle лише магічні, як змінні, що фактично викликає проблему AngularJS. Тобто проблема полягає в ін'єкції, а не в визначенні.

function MyCtrl($scope, myService) would get mangled to function MyCtrl(a, b), but the service definition inside of a string should never get altered.

  • Запуск ng-min перед запуском uglify вирішує цю проблему.
138
додано
Приємно! Чудова робота!
додано Автор Calvin Froedge, джерело
@Dan Kanze Fantastic, працював для мене. Дякую :)
додано Автор Mik378, джерело
Я потрапив у це саме те саме, коли використовую кутовий бутстрап + yeoman. Використовуючи кутовий генератор Yeoman , він створив збірку dist , яка б мала вказана помилка залежності "Невідомий постачальник". Налаштування mangle: false вирішило проблему. (примітка: проблема була лише проблемою в grunt побудованому dist> , а не розробнику привабливого app build)
додано Автор craigb, джерело
Я не рекомендую встановлювати мангл на істину. Встановіть перевірку того, який кутовий погляд на помилку: docs.angularjs.org/ tutorial/step_05 # a-note-on-minification . Це працювало для мене у досить великому кутовому додатку.
додано Автор ingaham, джерело
Чи mangle: true дійсно мангл "як рядки"? Я впевнений, що він лише магічний, як змінні , що фактично викликає проблему AngularJS. Тобто проблема полягає в ін'єкції, а не в визначенні. Функція MyCtrl ($ scope, myService) буде переміщена в функцію MyCtrl (a, b) , але визначення служби всередині рядка ніколи не повинно змінюватися. Запуск ng-min перед запуском uglify вирішує цю проблему, ні?
додано Автор Josh David Miller, джерело
Він оновив свій код. Його проблема полягала не в тому, що "$ locationProvider" став "b" або щось подібне. Це просто не спрацювало. Однак +1 для цієї відповіді :)
додано Автор AndreM96, джерело
Спасибі дуже важко знайти цей варіант.
додано Автор reen, джерело
ng-min тепер вичерпано на користь ng-annotate
додано Автор Atav32, джерело
Де я можу оновити об'єкт uglify, щоб позначити маглю: false?
додано Автор BPWDevelopment, джерело
працював для мене! Дякую
додано Автор Jacob, джерело

Проблема

З AngularJS: погані частини :

Angular has a built in dependency injector that will pass appropriate objects to your function based on the names of its parameters:

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

Here, the names of the parameters $scope and $window will be matched against a list of known names, and corresponding objects get instantiated and passed to the function. Angular gets the parameter names by calling toString() on the function, and then parsing the function definition.

The Проблема with this, of course, is that it stops working the moment you minify your code. Since you care about user experience you will be minifying your code, thus using this DI mechanism will break your app. In fact, a common development methodology is to use unminified code in development to ease debugging, and then to minify the code when pushing to production or staging. In that case, this Проблема won’t rear its ugly head until you’re at the point where it hurts the most.

(...)

Since this dependency injection mechanism doesn’t actually work in the general case, Angular also provides a mechanism that does. To be sure, it provides two. You can either pass along an array like so:

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

Or you can set the $inject property on your constructor:

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

Рішення

Ви можете використовувати ng-annotate для автоматичного додавання анотацій, необхідних для мінімізації:

ng-annotate додає та видаляє введення AngularJS залежностей   анотації Це не ненав'язливо, тому ваш вихідний код залишається точно таким   той же інакше. Немає втрачених коментарів або переміщених рядків.

ng-annotate is faster and stabler than ngmin (which is now deprecated) and it has plugins for many tools:


Починаючи з AngularJS 1.3, в ngApp з'являється новий парам, який називається ngStrictDi :

якщо цей атрибут присутній у елементі програми, інжектор буде   створено в режимі "строго-ді". Це означає, що програма не зможе   викликати функції, які не використовують явну анотацію функцій (і   таким чином, не підходять для мінімізації), як описано в Залежність   Інструкція з ін'єкцій , а корисна інформація для налагодження допоможе у відстеженні   вниз корінь цих помилок.

49
додано
це було виправлення, я шукав днів!
додано Автор jack.the.ripper, джерело
+1 ng-annotate виправлено проблему для мене теж :)
додано Автор nacholibre, джерело
@BigDong, якщо ви використовуєте браузер, найкращий спосіб - це, можливо, включити ngStrictDi (щось на кшталт <div ng-app = "myApp" ng-strict-di /> ) і використовуйте gulp-ng-annotate навіть у своєму середовищі розробки, щоб ви легко відстежували ці помилки.
додано Автор Paolo Moretti, джерело
@Willa переконайтеся, що залежність, яку ви намагаєтеся завантажити, фактично включена в мінімізований пакет.
додано Автор Paolo Moretti, джерело
Я стикаюсь з однією і тією ж проблемою, будуючи мініфізований код, переглядаючи, нахиляючи та нахиляючи. Я зняв gyps minify і замінив його gulp-ng-annotate, кодекс все ще мінімізований, але все одно не працює.
додано Автор BigDong, джерело
@PaoloMoretti Я спробував з ngStrictDi та gulp-ng-annotate, браузерпізувати може пакет, але код не зменшений, чи не повинно бути ng-annotate роботу?
додано Автор BigDong, джерело
Я створюю свій контролер таким чином: .controller ('SomeCtrl', ['$ scope', function SomeCtrl ($ scope) Після перегляду файлу bundle.js я не бачу жодних змін за допомогою gulp-ng-annotate, так що Я щойно видалив плагін
додано Автор BigDong, джерело
+1 Просто перехід на grunt-ng-annotate виправлено цю проблему, і ngmin у будь-якому разі застаріє зараз, отже, це ще одна причина переходу.
додано Автор Pier-Luc Gendreau, джерело
Ми використовуємо MyController. $ Inject = [], але все одно він не працює. Цікаво, що може бути проблемою! Ми навіть використовуємо ng-annotate без успіху. Чи є ще щось, що може викликати це?
додано Автор Willa, джерело
@ ПаолоМоретті вибачте за пізню відповідь. У нас все ще є ця проблема. Насправді ми завантажуємо всі залежності тільки чудово. Я навіть розглянув мінімізовану версію всіх файлів, і я бачу, що контролер там визначений і зареєстрований кутовий. Я навіть намагався вимкнути переміщення змінної, але все одно я не можу отримати менш версію програми для роботи.
додано Автор Willa, джерело
Додавання ng-strict-di виправлено моє питання, дякую !!!
додано Автор Kris Boyd, джерело

Я отримав таку ж помилку. Однак для мене проблема полягає в декларації контролера директив. Ви повинні зробити це замість цього.

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

21
додано
Ви щойно зробили свій день
додано Автор clopez, джерело
Дякую @angelokh! Я мав саме цю проблему. Я використовував позначення controller: function ($ scope) {} .
додано Автор jbasko, джерело
Це більше схоже на вирішення актуальної проблеми, ніж mangle: false , запропоноване в інших відповідях, оскільки ми все ще хочемо, щоб ми могли керувати іменами.
додано Автор jbasko, джерело

У мене було подібне питання, використовуючи грунт, ngmin та uglify.

Я керував процесом у такому порядку: concat, ngmin, uglify

Я продовжував отримувати помилку $ injector від кутового, доки я не додавав у параметри 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']);

};

9
додано
Це зафіксувало мені фантастичну подяку
додано Автор Gurnard, джерело
Виправлено мою проблему мінімізації, спасибі!
додано Автор Benoit Wickramarachi, джерело
Дякую, ти дякую! це врятувало мені так багато часу.
додано Автор mylescc, джерело

Ідея AndrewM96 пропонується ng-min правильно.

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

5
додано
хоча в документах ng-min звучить обіцянка, що це не вирішує проблему
додано Автор special0ne, джерело
ng-min з'являється, просто обробляє кутові файли, щоб вони були дружніми до uglify . У процесі побудови ми використовуємо обидва ( ng-min перед uglify ) і все ще виникла проблема з uglified js.
додано Автор craigb, джерело
@ craigb має ту ж саму проблему. Може бути, це поєднання речей. Я також використовую RequireJS. Я в основному роблю всі функції, що змінюють, ng-min повинен робити сам і продовжує працювати ng-min, ніж запускати, потрібно запускати, а запускати uglify з мангою true. Цей процес, здається, працює в більшості випадків.
додано Автор escapedcat, джерело
Чому це позначено як відповідь? (Крім того, AndrewM96 повинен бути AndreM96)
додано Автор Jay, джерело

У мене була однакова проблема. І вирішив це наступним чином. Нам потрібно запустити модуль Gulp під назвою gulp-ng-annotate перед тим, як запустити uglify. Тому ми встановлюємо цей модуль

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

Потім виконайте вимогу в Gulpfile.js

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

І в твоїй ініціативі роблять щось подібне

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

Це вирішило це для мене.

[EDIT: виправлені помилки]

3
додано
gulp-MG-annotate має бути gulp-NG-annotate?
додано Автор hally9k, джерело
Так, вибачте за помилку. Де читання mg-annotate завжди є ng-annotate
додано Автор Paulo Borralho Martins, джерело

Uglify має можливість вимкнути керування окремими файлами:

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

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

2
додано
додавання "angualr" не вирішити проблему. Це не пресет.
додано Автор special0ne, джерело

Це дуже важко налагодити, тому що багато послуг називаються однаковими (переважно 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++
2
додано
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram