Angular and ngAnnotate, a Better Way

Posted by Peter Kellner on November 15, 2014 · 2 mins read
Ad: Learn Modern JavaScript on YouTube (3 Hours & Free)

I recently posted to StackOverflow a question and example of how adding a dependency injection to my AngularJS app did not seem to matter regarding my program running correctly.  The answer I got back was clear, but somewhat disconcerting.  Basically, the answer is that Angular takes care of the problem for me in development but when I move to production with minification, it will fail.  Well, that sucks on so many levels. Here is an example of code that shows the problem.

angular.module('svccApp', []);

  angular.module('svccApp').
  factory('bareService', [

    function() {
      var myValue = {};
      myValue.str1 = 'xyz';
      return myValue;
    }
  ]);

  angular.module('svccApp')
    .controller('MyController', MyController);

  // WHY IS THIS NOT NECESSARY?
  //MyController.$inject = ['$scope', 'bareService'];

  function MyController($scope, bareService) {
    $scope.testVal = bareService.str1;
  }

As it turns out, there are actually 4 things I can see doing to help mitigate the issue of deploying buggy code you don’t know about. (answers included from my stackoverflow post mentioned above)

  • Test Everything in minimized JavaScript
  • Add ng-strict-di to the div containing the ng-app tag
  • Add ngAnnotate to your build process to try and fix the error automagically
  • Force your gulp or grunt build process to fail if ngAnnotate find any issues

I like number 4 best.  below is my poorly written gulp task that does that as well as a screen shot of it finding an error.  It basically gives me the code to put back into my application so it will not fail again.

gulp.task('scripts', function (cb) {
    gulp.src(['public/app/**/*.js'])
        .pipe(concat('main.js'))
        .pipe(gulp.dest('scratchfiles'));


    return gulp.src(['scratchfiles/main.js'])
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('default'))
        .pipe(ngAnnotate())
        .pipe(diff())
        .pipe(diff.reporter({fail: true}))
        .pipe(gulp.dest('public/dist'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('public/dist'))
        .pipe(notify({message: 'Scripts task complete'}));
});

image

When I run the task above, the gulp diff command stops and shows me what ngAnnotate added to my JavaScript.  Then, I can go and add that myself and then my gulp build will work and it will not generate any errors.

At the moment, I can’t figure out how to get this task to stop my gulp build process so I have to run this task by itself.  I’d love to hear how to fix that also.  This is all pretty new to me.