Use ng-annotate for Gulp or Grunt and comment functions that need automated dependency injection using /* @ngInject */
Why?: This safeguards your code from any dependencies that may not be using minification-safe practices.
Why?: ng-min
is deprecated
I prefer Gulp as I feel it is easier to write, to read, and to debug.
The following code is not using minification safe dependencies.
angular
.module('app')
.controller('AvengersController', AvengersController);
/* @ngInject */
function AvengersController(storage, avengerService) {
var vm = this;
vm.heroSearch = '';
vm.storeHero = storeHero;
function storeHero() {
var hero = avengerService.find(vm.heroSearch);
storage.save(hero.name, hero);
}
}
When the above code is run through ng-annotate it will produce the following output with the $inject
annotation and become minification-safe.
angular
.module('app')
.controller('AvengersController', AvengersController);
/* @ngInject */
function AvengersController(storage, avengerService) {
var vm = this;
vm.heroSearch = '';
vm.storeHero = storeHero;
function storeHero() {
var hero = avengerService.find(vm.heroSearch);
storage.save(hero.name, hero);
}
}
AvengersController.$inject = ['storage', 'avengerService'];
Note: If ng-annotate
detects injection has already been made (e.g. @ngInject
was detected), it will not duplicate the $inject
code.
Note: When using a route resolver you can prefix the resolver’s function with /* @ngInject */
and it will produce properly annotated code, keeping any injected dependencies minification safe.
// Using @ngInject annotations
function config($routeProvider) {
$routeProvider
.when('/avengers', {
templateUrl: 'avengers.html',
controller: 'AvengersController',
controllerAs: 'vm',
resolve: { /* @ngInject */
moviesPrepService: function(movieService) {
return movieService.getMovies();
}
}
});
}
Note: Starting from Angular 1.3 you can use the
ngApp
directive’sngStrictDi
parameter to detect any potentially missing minification safe dependencies. When present the injector will be created in “strict-di” mode causing the application to fail to invoke functions which do not use explicit function annotation (these may not be minification safe). Debugging info will be logged to the console to help track down the offending code. I prefer to only useng-strict-di
for debugging purposes only.<body ng-app="APP" ng-strict-di>
Use gulp-ng-annotate or grunt-ng-annotate in an automated build task. Inject /* @ngInject */
prior to any function that has dependencies.
Why?: ng-annotate will catch most dependencies, but it sometimes requires hints using the /* @ngInject */
syntax.
The following code is an example of a gulp task using ngAnnotate
gulp.task('js', ['jshint'], function() {
var source = pkg.paths.js;
return gulp.src(source)
.pipe(sourcemaps.init())
.pipe(concat('all.min.js', {newLine: ';'}))
// Annotate before uglify so the code get's min'd properly.
.pipe(ngAnnotate({
// true helps add where @ngInject is not used. It infers.
// Doesn't work with resolve, so we must be explicit there
add: true
}))
.pipe(bytediff.start())
.pipe(uglify({mangle: true}))
.pipe(bytediff.stop())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(pkg.paths.dev));
});