Angular injector error with minified JavaScript

2019-08-15 05:48发布

问题:

I have been struggling to find a solution for this problem:

I am using Angular.js on my site.

I use CoffeeScript to write my JavaScript in Visual Studios 2012. When I save my CoffeeScript - both a minified and un-minified version of the JavaScript file is saved.

While using any minified version of JavaScript files on my webpage I keep getting this error:

Error: $injector:unpr Unknown Provider Unknown provider: nProvider <- n This error results from the $injector being unable to resolve a required dependency. To fix this, make sure the dependency is defined and spelled correctly. For example:

If I don’t use the minified version everything works fine.

Here is how I use angular to declare my App in each JavaScript file

(function() {
  var myApp;

  myApp = angular.module("myApp", ['uploaddirective']);

  myApp.controller("videoController", function($scope, $http, $compile) {

Can anyone help me to resolve this issue?

回答1:

Use array notation for minification-safe dependency injection:

myApp.controller("videoController", ['$scope', '$http', '$compile', function($scope, $http, $compile) {

Another option is to use build task to automatically annotate injections for you:

// @ngInject
myApp.controller("videoController", function($scope, $http, $compile) {

You will need grunt or gulp plugin for this, like ngAnnotate.

https://docs.angularjs.org/guide/di



回答2:

When you minifying the above code you will get something like

a.controller("videoController", function(x, y, z) {...

note that $scope, $http, $compile are replaced with x, y, z.

So when angular starts to execute Controller can't find the injectors because $scope, $http, $compile are replaced with x, y, z and there are no inject-able providers as x, y or z, so angular will trigger a error saying Unknown Provider.

solution 1

you can follow Inline Array Annotation as,

myApp.controller("videoController", ['$scope', '$http', '$compile', function($scope, $http, $compile) {...

after minifying this you will get something like

a.controller("videoController", ['$scope', '$http', '$compile', function(x, y, z) {...

minifying process doesn't effect on strings, here angular will use a array with strings that will match the providers. Here angular will match the x with $scope and so on.

solution 2

$inject Property Annotation

var MyController = function($scope, $http, $compile) {
    // controller function ...
}

MyController.$inject = ['$scope', '$http', '$compile'];

myApp.controller("videoController", MyController);

additionally check ng-annotate