0

I have a simple Angular app that is defined like so:

index.html

<body ng-app="waApp">
    <div ng-controller="IndexController">
        <h3>{[ test ]}</h3>
    </div>
</body>

waApp.js

(function() {

  var waApp = angular.module('waApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('{[');
    $interpolateProvider.endSymbol(']}');
  });

})();

IndexController.js

(function() {

  var waApp = angular.module('waApp');

  waApp.controller('IndexController', ['$scope', function($scope) {
    $scope.test = 'Angular Works, and Grunt too.';
  }]);

})();

As you can see, I already prepare for variable mangling during minification by using Angular's array syntax while defining a controller's dependencies.

Yet when I then concatenate all these files and minify them using Grunt, like so:

Gruntfile.js

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    concat: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
                '<%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      dist: {
        src: ['src/browser/js/*.js', 'src/browser/js/**/*.js'],
        dest: 'src/browser/public/js/app.js'
      }
    },

    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n',
        sourceMap: true,
        preserveComments: false,
        mangle: {
          except: ['angular']
        }
      },
      dist: {
        files: {
          'src/browser/public/js/app.min.js': ['<%= concat.dist.dest %>']
        }
      }
    }

  });

  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.registerTask('default', ['concat', 'uglify']);
};

I get the following error in my Chrome's debugger console:

Uncaught object head.js:18
(anonymous function) head.js:18
(anonymous function) head.js:46
q head.js:19
e head.js:45
ec head.js:48
c head.js:30
dc head.js:30
Wc head.js:29
(anonymous function) head.js:223
a head.js:156
(anonymous function) head.js:43
q head.js:19
c

head.js is simply a separate javascript file where I store angular.min.js (from the official source). When I don't minify my concatenated javascript, I don't get this error.

For completeness, the following are my concatenated and minified concatenated javascript files:

app.js (works)

/*! whataddress - v0.0.1-1 - 2014-06-26 */
(function() {

  var waApp = angular.module('waApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('{[');
    $interpolateProvider.endSymbol(']}');
  });

})();
(function() {

  var waApp = angular.module('waApp');

  waApp.controller('IndexController', ['$scope', function($scope) {
    $scope.test = 'Angular Works, and Grunt too.';
  }]);

})();

app.min.js (results in the error)

/*! whataddress 26-06-2014 */

!function(){angular.module("waApp",[],function(a){a.startSymbol("{["),a.endSymbol("]}")})}(),function(){var a=angular.module("waApp");a.controller("IndexController",["$scope",function(a){a.test="Angular Works, and Grunt too."}])}();
//# sourceMappingURL=app.min.js.map

Why does this happen even though I used Angular's array syntax for defining controller dependencies prior to minification?

Tom
  • 8,536
  • 31
  • 133
  • 232

1 Answers1

1

One error I spot in your app.js file is that you don't seem to prevent variable mangling for $interpolateProvider. In the app.min.js it is simply minified to a about which AngularJS knows nothing.

This might be the problem.

There is the grunt-ngmin plugin which does the variable mangling automatically for you. It is very convenient.

I know about it by using the Yeoman Angular Generator. This generator provides also a very useful Gruntfile.js which shows the usage of grunt-ngmin.

DanEEStar
  • 6,140
  • 6
  • 37
  • 52
  • Interesting, can I use grunt-ngmin for a single concatenated file rather than specifying multiple controllers and directives (PS. where are the services in the example?) ? Also, I wonder if it takes care of the config dependencies. – Tom Jun 26 '14 at 08:48
  • I have to admit in the project setup with angular generator it just works for everything. It will run the ngmin step on the already concatenated js file. It is hard to explain in this comment. You should check out the Gruntfile from Angular Generator. – DanEEStar Jun 26 '14 at 08:55