Change - Know that nothing stays the same

Gulp is not ready for Angular

September 17, 2015

Is part of my workflow try to know any new technology, and I was talking about Grunt/Gulp with some people and reading about it too.

Many people is saying to change to Gulp, than its faster than Grunt, its better code, its this and that.

I’ve tried to replace my current Grunt tasks with Grunt and I found this problems:

10 times slower to compile my code

Yes, it was ten times slower.

All my deploy process takes 1m 55s with grunt, this is for compile, upload, update bower and node, etc (if I dont need to update package, only run the commands to verify it).

When I finish to rewrite all my Gulp task, it was the moment to do a deploy, and I couldn’t do it, after more than 5 min of waiting when it was running the ‘build’ task with gulp I knew something was wrong.The way I was using gulp to integrate it with angular was using the code from generator-gulp-angular, is you create an proyect with this generator, your build task in gulp, looks like this for the part where it compiles:

return gulp.src(path.join(conf.paths.tmp, '/serve/*.html'))
    .pipe($.inject(partialsInjectFile, partialsInjectOptions))
    .pipe(assets = $.useref.assets())
    .pipe($.rev())
    .pipe(jsFilter)
    .pipe(debug())
    .pipe($.sourcemaps.init())
    .pipe($.ngAnnotate())
    .pipe($.uglify({ preserveComments: $.uglifySaveLicense })).on('error', conf.errorHandler('Uglify'))
    .pipe($.sourcemaps.write('maps'))
    .pipe(jsFilter.restore)
    .pipe(cssFilter)
    .pipe($.sourcemaps.init())
    .pipe($.replace('../../bower_components/bootstrap-sass/assets/fonts/bootstrap/', '../fonts/'))
    .pipe($.minifyCss({ processImport: false }))
    .pipe($.sourcemaps.write('maps'))
    .pipe(cssFilter.restore)
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.revReplace())
    .pipe(htmlFilter)
    .pipe($.minifyHtml({
      empty: true,
      spare: true,
      quotes: true,
      conditionals: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest(path.join(conf.paths.dist, '/')))
    .pipe($.size({ title: path.join(conf.paths.dist, '/'), showFiles: true }));
  });

Gulp pipes tasks, thats the big thing of gulp, but if you have a hard task like this, all the gulp magic goes to the trash. I couldn’t find a good way to track pipe time, trace errors, or put some info to debug (the only thing I’ve found was gulp-debug and it not very helpful).

My current grunt task to build my code code looks more or less like this:

module.exports = function(grunt) {
  grunt.registerTask('build', [
    'clean:dist',
    'env:all',
    'injector:sass',
    'concurrent:dist',
    'injector',
    'wiredep',
    'useminPrepare',
    'autoprefixer',
    'ngtemplates',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);
}

And it takes 10% or less of the time used by Gulp.Trying to find if I was doing my worst code in my life, I started to look for this issue and I’ve found many more with the same issue:

And when I tried to see which module was the biggest problem I got this:

where you can see a pull-request to start to understand the Gulp slow problem.

Better code

Not comfortable with Grunt, but from my experience if you can not track time per pipe in an easy way, debug whats going on, and avoid 10 pipes only to maintain in memory your process… is not the solution I’ll use.

PS: If you are using Angular and your project has more than 100 js files, and you use Gulp with a compile time below to 3m, please provide a link to your gulp config/tasks to build that example. It should be great to see a good AngularJS app working with gulp.


Agustin Vinao
Agustin Vinao.

Paradox: Life is a mystery. Don't waste time trying to figure it out.
Humor: Keep a sense of humor, especially about yourself. It is a strength beyond all measure.
Change: Know that nothing stays the same.