jerkovicl
10/7/2014 - 12:43 PM

AngularJS Gulpfile with ng-annotate

AngularJS Gulpfile with ng-annotate

//two main tasks are 'gulp watch' and 'gulp build'

//dependencies:
var gulp = require('gulp');
    //to use in conjunction with chrome plugin:
    livereload = require('gulp-livereload');
    //for css:
    sass = require('gulp-sass');
    less = require('gulp-less');
    sourcemaps = require('gulp-sourcemaps');
    autoprefixer = require('gulp-autoprefixer');
    minifycss = require('gulp-minify-css');
    rename = require('gulp-rename');
    //for javascript:
    jshint = require('gulp-jshint');
    stripDebug = require('gulp-strip-debug');
    uglify = require('gulp-uglify');
    concat = require('gulp-concat');
    //for cleaning out dist/ directory before build:
    rimraf = require('gulp-rimraf');
    //angular-specific:
    ngAnnotate = require('gulp-ng-annotate');
    htmlify = require('gulp-angular-htmlify');
    //for bundling up js bower dependencies into one vendor file on build:
    mainBowerFiles = require('main-bower-files');
    gulpFilter = require('gulp-filter');
    useref = require('gulp-useref');
    //for notifications about finished tasks
    notify = require("gulp-notify");

//paths object to save file paths for ease as gulpfile gets larger
var paths = {
  dev: {
    css: 'app/public/css',
    html: 'app/public/**/*.html',
    sass: 'app/public/scss/*.scss',
    less: 'app/public/less/*.less',
    js: 'app/public/js/**/*.js',
    bower: 'app/bower_components/**'
  },
  build: {
    main: 'dist/',
    css: 'dist/public/css',
    js: 'dist/public/js'
  }
};

//for now, only used in bower-files task
var jsFilter = gulpFilter('*.js');

//watch for changes and compile css and run jshint on those changes
//also use livereload to automatically reload page
gulp.task('watch', function() {
  livereload.listen();
  gulp.watch(paths.dev.html).on('change', livereload.changed);
  gulp.watch(paths.dev.less, ['styles']).on('change', livereload.changed);
  //gulp.watch(paths.dev.sass, ['styles']).on('change', livereload.changed);
  gulp.watch(paths.dev.js, ['lint']).on('change', livereload.changed);
});

//watch less for changes and render into minified css with nice auto-prefixing
gulp.task('styles', function() {
    
    var notifierOptions = {
        message: 'LESS file generated',
        onLast: true
    };
    
  return gulp.src(paths.dev.less)
    .pipe(sourcemaps.init())
    .pipe(less({compress: true}))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1'))
    .pipe(concat('main.css'))
    .pipe(rename({suffix: '.min'}))
    .pipe(sourcemaps.write('app/public/css'))
    .pipe(minifycss())
    .pipe(gulp.dest('app/public/css'))
    .pipe(notify(notifierOptions));
});

//stylish output for errors
gulp.task('lint', function() {
  return gulp.src([paths.dev.js, '!./app/public/bower_components/**'])
  .pipe(jshint()).on('error', errorHandler)
  .pipe(jshint.reporter('jshint-stylish'))
  .pipe(jshint.reporter('fail'));
});

gulp.task('strip-debug', function () {
     return gulp.src(['./app/public/js/**/*.js', '!./app/public/bower_components/**']) //gulp.src('src/app.js')
        .pipe(stripDebug())
        .pipe(gulp.dest(paths.build.js)) //gulp.dest('dist')
});

//build task, with other tasks as dependencies and then javascript handling in anonymous function
gulp.task('build', ['bower-files', 'copy-css', 'copy-server', 'copy-html-files'], function() {
    return gulp.src(['./app/public/js/**/*.js', '!./app/public/bower_components/**'])
    .pipe(stripDebug()) //remove console logs
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(concat('app.min.js'))
    .pipe(gulp.dest(paths.build.js))
    .pipe(notify("build task finished"));
});

//task to clear out dist/ folder befor building out deployment version of app - runs before every other task in 'gulp build'
gulp.task('empty-dist', function() {
  return gulp.src(paths.build.main, { read: false })
    .pipe(rimraf());
});

//copy minified CSS over to /dist
gulp.task('copy-css', ['empty-dist'], function () {
  return gulp.src('./app/public/css/*.css')
    .pipe(gulp.dest('dist/public/css'));
});

//copy html files into build directory, apply html5 data prefix to angular
gulp.task('copy-html-files', ['empty-dist'], function () {
  var assets = useref.assets();

  return gulp.src('./app/public/**/*.html')
    .pipe(assets)
    .pipe(htmlify())
    .pipe(assets.restore())
    .pipe(useref())
    .pipe(gulp.dest('dist/public'));
});

//copy over express server into dist/ folder
gulp.task('copy-server', ['empty-dist'], function () {
  return gulp.src('./app/server.js')
  .pipe(gulp.dest('dist/'));
})

//deal with getting bower dependencies into dist/index.html bower and minify and concat bower js into vendor.min.js
gulp.task("bower-files", ['empty-dist'], function(){
  return gulp.src(mainBowerFiles())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(concat('vendor.min.js'))
    .pipe(gulp.dest("dist/public/js"));
});

//error handler helper for jshint
function errorHandler (error) {
  this.emit('end');
}