Minification and Annotation

ou Minificação e Anotação

ng-annotate

  • Use ng-annotate para Gulp ou Grunt e comente as funções que precisam de injeção de dependência automatizada usando /** @ngInject */

    Por que? Isso protege seu código de qualquer dependência que pode não estar usando práticas seguras para minificação.

    Por que? ng-min está deprecated.

    Eu prefiro Gulp pois sinto que é mais fácil de escrever, de ler, e de debugar.

    O código a seguir não está usando dependências seguras para minificação.

    angular
        .module('app')
        .controller('Avengers', Avengers);
    
    /* @ngInject */
    function Avengers(storageService, avengerService) {
        var vm = this;
        vm.heroSearch = '';
        vm.storeHero = storeHero;
    
        function storeHero(){
            var hero = avengerService.find(vm.heroSearch);
            storageService.save(hero.name, hero);
        }
    }
    

    Quando o código acima é executado através de ng-annotate produzirá a seguinte saída com a anotação $inject e se tornará seguro para minificação.

    angular
        .module('app')
        .controller('Avengers', Avengers);
    
    /* @ngInject */
    function Avengers(storageService, avengerService) {
        var vm = this;
        vm.heroSearch = '';
        vm.storeHero = storeHero;
    
        function storeHero(){
            var hero = avengerService.find(vm.heroSearch);
            storageService.save(hero.name, hero);
        }
    }
    
    Avengers.$inject = ['storageService', 'avengerService'];
    

    Nota: Se ng-annotate detectar que a injeção já foi feita (por ex. @ngInject foi detectado), o código do $inject não será duplicado.

    Nota: Quando usar um resolvedor de rotas você pode prefixar a função do resolvedor com /* @ngInject */ o que produzirá código devidamente anotado, mantendo qualquer dependência injetada segura para minificação.

    // Usando anotação @ngInject
    function config($routeProvider) {
        $routeProvider
            .when('/avengers', {
                templateUrl: 'avengers.html',
                controller: 'Avengers',
                controllerAs: 'vm',
                resolve: { /* @ngInject */
                    moviesPrepService: function(movieService) {
                        return movieService.getMovies();
                    }
                }
            });
    }
    

    Nota: A partir do Angular 1.3 use o parâmetro ngStrictDi da diretiva ngApp. Quando presente, o injetor será criado no modo "strict-di" fazendo com que a aplicação falhe ao tentar invocar funções que não usem anotação explícita de função (elas podem não ser seguras para minificação). Informação de debug será logada no console para ajudar a rastrear o código ofensivo. <body ng-app="APP" ng-strict-di>

Utilize Gulp ou Grunt para o ng-annotate

  • Utilize gulp-ng-annotate ou grunt-ng-annotate para tarefas de build automatizadas. Injete /* @ngInject */ antes de qualquer função que tenha dependências.

    Por que? ng-annotate vai capturar todas as dependências, mas as vezes requer dicas utilizando a sintaxe /* @ngInject */ .

    O código abaixo é um exemplo de uma task Gulp utilizando 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));
    });
    

De volta ao topo