title: How to Minify ES6 Using Gulp
body: <p>I am relatively new to writing a <code>gulpfile.js</code> manually. I have a Backbone and Marionette based project where the gulp file so far looked like the following:</p>
  
  <pre><code>var gulp = require('gulp');
  var $ = require('gulp-load-plugins')();
  var browserify = require('browserify');
  var del = require('del');
  var watchify = require('watchify');
  var source = require('vinyl-source-stream');
  var stylish = require('jshint-stylish');
  var buffer = require('vinyl-buffer');
  var _ = require('lodash');
  
  var browserSync = require('browser-sync').create();
  var reload = browserSync.reload;
  
  gulp.task('clean', function(cb) {
    return del([
      'app/tmp'
    ], cb);
  });
  
  gulp.task('html', function() {
    return gulp.src('./src/index.html')
      .pipe($.plumber())
      .pipe(gulp.dest('./dist'));
  });
  
  gulp.task('images', function() {
    gulp.src(['./src/assets/images/*.jpg', './src/assets/images/*.svg', './src/assets/images/*.gif',
      './src/assets/images/*.png'
    ])
    .pipe(gulp.dest('./dist/images'));
  });
  
  gulp.task('vendor-css', function() {
    gulp.src(['./src/assets/styles/vendor/*.css'
    ])
    .pipe(gulp.dest('./dist'));
  });
  
  gulp.task('fonts', function() {
    gulp.src(['./src/assets/fonts/*.eot', './src/assets/fonts/*.woff', './src/assets/fonts/*.ttf', 
      './src/assets/fonts/*.svg'
    ])
    .pipe(gulp.dest('./dist/fonts'));
  });
  
  gulp.task('styles', function() {
    return gulp.src('./src/main.styl')
      .pipe($.stylus())
      .pipe($.autoprefixer())
      .pipe($.rename('bundle.css'))
      .pipe(gulp.dest('./dist'))
      .pipe(reload({ stream: true }));
  });
  
  var bundler = _.memoize(function(watch) {
    var options = {debug: true};
  
    if (watch) {
      _.extend(options, watchify.args);
    }
  
    var b = browserify('./src/main.js', options);
  
    if (watch) {
      b = watchify(b);
    }
  
    return b;
  });
  
  var handleErrors = function() {
    var args = Array.prototype.slice.call(arguments);
    delete args[0].stream;
    $.util.log.apply(null, args);
    this.emit('end');
  };
  
  function bundle(cb, watch) {
    return bundler(watch).bundle()
      .on('error', handleErrors)
      .pipe(source('bundle.js'))
      .pipe(buffer())
      .pipe($.sourcemaps.init({ loadMaps: true }))
      .pipe($.sourcemaps.write('./'))
      .pipe(gulp.dest('./dist'))
      .on('end', cb)
      .pipe(reload({ stream: true }));
  }
  
  gulp.task('scripts', function(cb) {
    bundle(cb, true);
  });
  
  gulp.task('jshint', function() {
    return gulp.src(['./src/**/*.js', './test/**/*.js'])
      .pipe($.plumber())
      .pipe($.jshint())
      .pipe($.jshint.reporter(stylish));
  });
  
  var reporter = 'spec';
  
  gulp.task('mocha', ['jshint'], function() {
    return gulp.src([
      './test/setup/node.js',
      './test/setup/helpers.js',
      './test/unit/**/*.js'
    ], { read: false })
      .pipe($.plumber())
      .pipe($.mocha({ reporter: reporter }));
  });
  
  gulp.task('build', [
    'clean',
    'html',
    'images',
    'vendor-css',
    'fonts',
    'styles',
    'scripts',
    'test'
  ]);
  
  gulp.task('test', [
    'jshint'
  ]);
  
  gulp.task('watch', ['build'], function() {
    browserSync.init({
      server: {
        baseDir: 'dist'
      }
    });
  
    reporter = 'dot';
    bundler(true).on('update', function() {
      gulp.start('scripts');
      gulp.start('test');
    });
    gulp.watch('./test/**/*.js', ['test']);
    gulp.watch(['./src/main.styl', './src/pages/**/*.styl', './src/assets/styles/*.styl'], ['styles']);
    gulp.watch(['./src/*.html'], ['html']);
  });
  
  gulp.task('default', ['watch']);
  </code></pre>
  
  <p>Now I need to enable minification of Javascript for which I referred to the following <a href="https://www.npmjs.com/package/gulp-uglify" rel="noreferrer">link</a>. I am using the one with <code>uglify-js-harmony</code> as the minifier for ES6 support since most of my code is using ES6 syntax. The modified gulp file looks like the following:</p>
  
  <pre><code>var gulp = require('gulp');
  var $ = require('gulp-load-plugins')();
  var browserify = require('browserify');
  var del = require('del');
  var watchify = require('watchify');
  var source = require('vinyl-source-stream');
  var stylish = require('jshint-stylish');
  var buffer = require('vinyl-buffer');
  var uglifyjs = require('uglify-js-harmony');
  var minifier = require('gulp-uglify/minifier');
  var pump = require('pump');
  var _ = require('lodash');
  
  var browserSync = require('browser-sync').create();
  var reload = browserSync.reload;
  
  gulp.task('clean', function(cb) {
    return del([
      'app/tmp'
    ], cb);
  });
  
  gulp.task('html', function() {
    return gulp.src('./src/index.html')
      .pipe($.plumber())
      .pipe(gulp.dest('./dist'));
  });
  
  gulp.task('images', function() {
    gulp.src(['./src/assets/images/*.jpg', './src/assets/images/*.svg', './src/assets/images/*.gif',
      './src/assets/images/*.png'
    ])
    .pipe(gulp.dest('./dist/images'));
  });
  
  gulp.task('vendor-css', function() {
    gulp.src(['./src/assets/styles/vendor/*.css'
    ])
    .pipe(gulp.dest('./dist'));
  });
  
  gulp.task('fonts', function() {
    gulp.src(['./src/assets/fonts/*.eot', './src/assets/fonts/*.woff', './src/assets/fonts/*.ttf', 
      './src/assets/fonts/*.svg'
    ])
    .pipe(gulp.dest('./dist/fonts'));
  });
  
  gulp.task('styles', function() {
    return gulp.src('./src/main.styl')
      .pipe($.stylus())
      .pipe($.autoprefixer())
      .pipe($.rename('bundle.css'))
      .pipe(gulp.dest('./dist'))
      .pipe(reload({ stream: true }));
  });
  
  var bundler = _.memoize(function(watch) {
    var options = {debug: true};
  
    if (watch) {
      _.extend(options, watchify.args);
    }
  
    var b = browserify('./src/main.js', options);
  
    if (watch) {
      b = watchify(b);
    }
  
    return b;
  });
  
  var handleErrors = function() {
    var args = Array.prototype.slice.call(arguments);
    delete args[0].stream;
    $.util.log.apply(null, args);
    this.emit('end');
  };
  
  function bundle(cb, watch) {
    return bundler(watch).bundle()
      .on('error', handleErrors)
      .pipe(source('bundle.js'))
      .pipe(buffer())
      .pipe($.sourcemaps.init({ loadMaps: true }))
      .pipe($.sourcemaps.write('./'))
      .pipe(gulp.dest('./dist'))
      .on('end', cb)
      .pipe(reload({ stream: true }));
  }
  
  gulp.task('scripts', function(cb) {
    bundle(cb, true);
  });
  
  gulp.task('jshint', function() {
    return gulp.src(['./src/**/*.js', './test/**/*.js'])
      .pipe($.plumber())
      .pipe($.jshint())
      .pipe($.jshint.reporter(stylish));
  });
  
  gulp.task('compress', function (cb) {
    var options = {
      preserveComments: 'license'
    };
  
    pump([
        gulp.src('./dist/bundle.js'),
        minifier(options, uglifyjs),
        gulp.dest('./dist')
      ],
      cb
    );
  });
  
  var reporter = 'spec';
  
  gulp.task('mocha', ['jshint'], function() {
    return gulp.src([
      './test/setup/node.js',
      './test/setup/helpers.js',
      './test/unit/**/*.js'
    ], { read: false })
      .pipe($.plumber())
      .pipe($.mocha({ reporter: reporter }));
  });
  
  gulp.task('build', [
    'clean',
    'html',
    'images',
    'vendor-css',
    'fonts',
    'styles',
    'scripts',
    'test',
    'compress'
  ]);
  
  gulp.task('test', [
    'jshint'
  ]);
  
  gulp.task('watch', ['build'], function() {
    browserSync.init({
      server: {
        baseDir: 'dist'
      }
    });
  
    reporter = 'dot';
    bundler(true).on('update', function() {
      gulp.start('scripts');
      gulp.start('test');
    });
    gulp.watch('./test/**/*.js', ['test']);
    gulp.watch(['./src/main.styl', './src/pages/**/*.styl', './src/assets/styles/*.styl'], ['styles']);
    gulp.watch(['./src/*.html'], ['html']);
  });
  
  gulp.task('default', ['watch']);
  </code></pre>
  
  <p>Now, when I run <code>gulp</code> the task for compressing starts, does not give any error but never finishes and the build (dist) is made same as before <strong>(no minification happens!)</strong> . Do I need to somehow integrate this compression task into the <code>bundle</code> function using another <code>.pipe</code> or am I doing  something else in a wrong way here ? 
  Also, is it correct to do the minification after the <code>bundle.js</code> is created which is what am attempting to do here or does it need to be at the stage when the source files are still not concatenated ?</p>