Angularjs minification using grunt uglify resulting in js error
Solution 1
You have to use the string-injection based syntax that ensure that the minified version points to the good dependancy :
function checkInCtrl ($scope, $rootScope, $location, $http){}
becomes :
['$scope', '$rootScope', '$location', '$http', function checkInCtrl ($scope, $rootScope, $location, $http){}]
Solution 2
Navdeep,
The suggested solution from Bixi will work. However the easier way is just to use ngmin Grunt plugin. Using this plugin, you don't need to handle the dependency injection like what you did and also no need for the special syntax like Bixi.
To use it, make sure you have grunt-ngmin
and that you call it before uglify.
Your Gruntfile.js:
ngmin: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
....
grunt.registerTask('build', [
'ngmin',
'uglify',
]);
Solution 3
For info, ngMin has been deprecated. You should use ngAnnotate instead which works beautifully with grunt and gulp.
Solution 4
Getting uglify and minify to work will reveal (as it did in my case) places where injected variables are changed from something like $scope to 'a' Example: This code:
controller: function($scope) {
$scope.showValidation= false;
this.showValidation = function(){
$scope.showValidation = true;
};
}
after minify and uglify becomes:
controller:function(a){a.showValidation=!1,this.showValidation=function(){a.showValidation=!0}}
And you get an error because 'a' is not the same as $scope.
Solution is to explicitly declare the injected variables:
controller: ['$scope', function($scope) {
$scope.showValidation= false;
this.showValidation = function(){
$scope.showValidation = true;
};
}]
after minify and uglify becomes:
controller:["$scope",function(a){a.showValidation=!1,this.showValidation=function(){a.showValidation=!0}}]
Now 'a' is mapped to $scope.
Navdeep
Javascript Developer - Have excellent grip over javascript language. I have worked on nodejs, expressjs, socketio, phonegap, angularjs, sailsjs.
Updated on July 16, 2020Comments
-
Navdeep almost 4 years
In angularjs we pass parameters as dependency injection. For example,
function checkInCtrl ($scope, $rootScope, $location, $http){ ….. …. }
So when it gets minified, it becomes like,
function checkInCtrl(a,b,c,d){ }
Now a,b,c,d won’t be interpreted as $scope, $rootScope, $location, $http respectively by angular and whole code fails to work. For this angularjs has provided one solution, which is
checkInCtrl.$inject = ['$scope', '$rootScope', $location', '$http'];
we can inject different dependencies by using above syntax. This worked well till I didn’t use some custom angular service as dependency. So for example ,
if I have something like
function checkInCtrl ($scope, $rootScope, $location, $http){ ….. …. }
It works with given solution, but if I have something like
function checkInCtrl ($scope, $rootScope, $location, $http, customService){ ….. …. }
Where customService is something like
angular.module(customService, ['ngResource']) .factory('abc', function($resource) { return $resource('/abc'); })
It’s minified version doesn’t get interpreted properly by angular.
As we had to start project development activities, we couldn’t spend enough time to look into matter and we started using controller without minifying them. So first question is whether there is such problem with angular or I made some mistake and due to which it didn't work? If such issue exist,what is solution to it?
-
Navdeep about 10 yearsHey Bixi, both 'checkInCtrl.$inject = ['$scope', '$rootScope', $location', '$http']' and '['$scope', '$rootScope', '$location', '$http', function checkInCtrl ($scope, $rootScope, $location, $http){}]' work the same way. I have used first one. The problem is when we use a custom service as one of the parameter in function
-
Jscti about 10 yearsWell when your code is uglified, only the second one will work
-
Navdeep about 10 yearsThe problem is when we use a custom service as one of the parameter in function otherwise first solution works, so are you saying solution suggested by you will work for custom service as well?
-
Jscti about 10 yearsYeah, it's designed to handle custom or standard dependancies. Take a look here for example : thegreenpizza.github.io/2013/05/25/…
-
ngasull about 10 yearsIf you'd like to understand AngularJS's dependency injection concepts deeply, I strongly recommend you to check the doc: docs.angularjs.org/guide/di Enjoy!
-
Navdeep about 10 yearsThanks Bixi, it works and thanks for the link [link]thegreenpizza.github.io/2013/05/25/… It has some good information. Blint, thanks for angularjs doc link as well.
-
Navdeep about 10 yearsHey Lee, This is the simplest way to achieve minification for an angular app. It also works. So thanks. But the drawback that I observed was that minified file size was almost double than the size of file created using uglify.
-
suriyanto about 10 yearsI tested my project with both ngmin and without ngmin, but can't seem to see the difference. You ended up only with 2 js file: scripts.js and vendor.js, right? Which of these 2 files have the biggest size difference?
-
Navdeep about 10 yearsHey @Bixi, there is one more question. The link you shared has details of how to define a controller, a factory, a service or a directive to avoid problem after minification. But what would be syntax when there are multiple modules and one module is dependent on other. So what will be syntax for
angular.nodule('X',['Y','Z'])
? I don't have multiple modules in this project, but want to know if syntax is different. -
Navdeep about 10 yearsHey Lee, I am creating one consolidated uglified file of all my controller files using ngmin and thus generated file is double in size than file generated using uglify.
-
Ankit Gupta over 9 years@Cétia I have another case,I have some third party API in which this is written domUtilityService.digest = function($scope) { } now $scope is minified into a and getting error,my minification tool is not annotating this,any idea about that?
-
Mohamed Ali about 7 yearsit's the first time for me to know what the string injection based syntax is for!
-
Youcef Moulahoum almost 6 yearsThanks a lot @Cétia , your response helped me to face a big problem and also allow me to know what the string injection is used for ! thanks again !