Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Minify ES6 Using Gulp

I am relatively new to writing a gulpfile.js manually. I have a Backbone and Marionette based project where the gulp file so far looked like the following:

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']);

Now I need to enable minification of Javascript for which I referred to the following link. I am using the one with uglify-js-harmony as the minifier for ES6 support since most of my code is using ES6 syntax. The modified gulp file looks like the following:

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']);

Now, when I run gulp the task for compressing starts, does not give any error but never finishes and the build (dist) is made same as before (no minification happens!) . Do I need to somehow integrate this compression task into the bundle function using another .pipe or am I doing something else in a wrong way here ? Also, is it correct to do the minification after the bundle.js 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 ?

like image 682
Nikhil Khullar Avatar asked Jul 18 '16 18:07

Nikhil Khullar


People also ask

Does Uglify support ES6?

uglify-es is no longer maintained and uglify-js does not support ES6+.

Does Uglify minify?

To 'uglify' a JavaScript file is to minify it using Uglify. Uglification improves performance while reducing readability.


1 Answers

  1. Clone https://github.com/terinjokes/gulp-uglify/
  2. Locate https://github.com/terinjokes/gulp-uglify/blob/80da765a266cb7ff9d034a73bde0abe18d72d6de/package.json#L13 in prefered checkout (prefered latest)
  3. Set version for uglify-js to mishoo/UglifyJS2#harmony (shortcut for https://github.com/mishoo/UglifyJS2#harmony)

Note that this is a temporary set-up until there is an official release of uglify supporting harmony

like image 115
avdg Avatar answered Oct 23 '22 03:10

avdg