How to fix injector error after Angular minification build?

后端 未结 3 1551
南笙
南笙 2021-01-18 04:03

Before speaking, I read about it made ​​recommendations but still causing error. Look the short code:

function IndexController($scope, $route, $routeParams,         


        
相关标签:
3条回答
  • 2021-01-18 04:22

    This is due to your minification, specifically options to minify and mangle your variable names.

    Angular determines what value to inject into your functions from the name of the parameters. For example...

    angular.factory('MyFactory', function($location) {...});
    

    ...will cause angular to look for whatever dependency is named '$location' and then call your function with the $location value passed as it's parameter.

    When you minify your javascript, with an option called mangle turned on, then the variable names get mangled. The previous function will turn into this...

    angular.factory('MyFactory', function(a) {...});
    

    Angular no longer has the correct parameter name in your source code, as $location is now a. This saves on size of your javascript but totally destroys Angular's implicit dependency resolution. You can solve this in one of two ways.

    The first is a feature that angular provides for you.

    angular.factory('MyFactory', ['$location', function(a) {...}]);
    

    You provide the names of the parameters in an array, with the last element of the array being the function to inject the parameters into. This way, it doesn't matter what you call your parameters in the code, and the minifier will never change a string literal so Angular always knows what you're wanting.

    The other way if you don't want to lose the convenience of not having to use the array notation is to turn off the mangle setting on your minifier. This obviously means you don't minify to the same degree, but ask yourself if it's really worth those extra bytes.

    A halfway house is to use something like ngMin, to allow annotation of the array notation into your code and then continue with the minification. This is the best of both world's imo, but increases the complexity of deploying your clientside js.

    EDIT

    The correct settings to turn off the mangle behaviour in grunt would be this...

    uglify: {
      options: {
        report: 'min',
        mangle: false
      }
    }
    

    But the ngAnnotate package can avoid this. See here for more info. (ngAnnotate is the package that has taken over ngMin)

    0 讨论(0)
  • 2021-01-18 04:23

    I had this problem and it took me a lot of time to figure out what the issue was because I tried disabling mangling of variable names, using $inject array instead of just passing the services and provider names to function definitions while relying on angular implicit dependency injection but still the problem persisted. It turned out that in one of my controller which uses IIFE, was missing semicolon at the end. Look at the code below.

    Before:

    (function(){

    })()

    The above code works okay before minification due to automatic semicolon insertion but it breaks after minification because the absence of semicolon screw things up. So after correction it looked like below.

    Correct:

    (function(){

    })();

    This fixed my problem. I hope this might help some one Note: I use grunt useminPrepare, usemin, copy, uglify and ngAnnotate.

    0 讨论(0)
  • 2021-01-18 04:45

    I've had a similar problem. It turned out that I was not properly identifying and formatting the dependencies for controllers and services, etc. I believe I discovered this by looking at the minification output. (It was rough, let me tell you.)

    Basically I had to look through all my files and verify that the dependency list matched what I was using in my controllers and services. It's strange because it worked without the changes.

    Here is an example of what I had to do:

    Original:

    angular.module('FootCtrl', []).controller('FooterController', function($scope) {
        $scope.footer = 'Copyright \u00A9 ' + new Date().getFullYear() + name;
    });
    

    Fixed

    angular.module('FootCtrl', []).controller('FooterController', ["$scope", function($scope) {
        $scope.footer = 'Copyright \u00A9 ' + new Date().getFullYear() + name;
    }]);
    

    Maybe take note of where I use single quotes vs. double quotes as well.

    Hopefully this helps a bit. I'm not sure if you have more code than what is shown- if not, I'm not too sure.

    0 讨论(0)
提交回复
热议问题