How to minify ES6 functions with gulp-uglify?

Viewed 53917

When I run gulp I get the following error:

[12:54:14] { [GulpUglifyError: unable to minify JavaScript]
cause:
{ [SyntaxError: Unexpected token: operator (>)]
 message: 'Unexpected token: operator (>)',
 filename: 'bundle.js',
 line: 3284,
 col: 46,
 pos: 126739 },
plugin: 'gulp-uglify',
fileName: 'C:\\servers\\vagrant\\workspace\\awesome\\web\\tool\\bundle.js',
showStack: false }

The offending line contains an arrow function:

let zeroCount = numberArray.filter(v => v === 0).length

I know I can replace it with the following to remedy the minification error by abandoning ES6 syntax:

let zeroCount = numberArray.filter(function(v) {return v === 0;}).length

How can I minify code containing ES6 features via gulp?

9 Answers

The accepted answer doesn't really answer how to minify straight es6. If you want to minify es6 without transpiling, gulp-uglify v3.0.0 makes that possible:

Update March 2019

Using my original answer, you definitely want to replace the uglify-es package with terser, as it seems uglify-es is no longer being maintained.

Original answer, still works:

1.) First, upgrade your gulp-uglify package to > 3.0.0 If you're using yarn and want to update to the latest version:

yarn upgrade gulp-uglify --latest

2.) Now you can use uglify-es, the "es6 version" of uglify, as so:

const uglifyes = require('uglify-es');
const composer = require('gulp-uglify/composer');
const uglify = composer(uglifyes, console);

gulp.task('compress', function () {
    return gulp.src('src/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
});

For more info: https://www.npmjs.com/package/gulp-uglify

You actually can uglify ES6 code without transpilation. Instead of gulp-uglify plugin, use gulp-uglifyes plugin.

var gulp = require('gulp');
var rename = require('gulp-rename'); 
var uglify = require('gulp-uglifyes');
var plumber = require('gulp-plumber');
var plumberNotifier = require('gulp-plumber-notifier');
var sourcemaps = require('gulp-sourcemaps');
var runSequence = require('run-sequence').use(gulp);

gulp.task('minjs', function () {
  return gulp.src(['/dist/**/*.js', '!/dist/**/*.min.js'])
    .pipe(plumberNotifier())
    .pipe(sourcemaps.init())
    .pipe(uglify({ 
       mangle: false, 
       ecma: 6 
    }))
    .pipe(rename(function (path) {
      path.extname = '.min.js';
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('/dist'));
});

gulp-uglify:

For ES6 and newer.

  1. install: npm install --save-dev gulp-uglify
  2. install: npm install --save-dev gulp-babel @babel/core @babel/preset-env

Usage:

const gulp = require('gulp'); 
const uglify = require('gulp-uglify');
const babel = require('gulp-babel');

gulp.task('script', () => {
    return gulp.src('src/**/*.js')
        .pipe(babel({
            presets: ['@babel/env']
        }))
        .pipe(uglify())
        .pipe(gulp.dest('src/dist'))
});

I worked at this for a while before getting it to work. As other answers have stated the problem is that gulp-uglify doesn't support ES6. gulp-uglify-es does, however if is no longer maintained. Terser is recommended by others, but it doesn't play well with gulp and using it with pipe().

If you use gulp-uglify as I do your gulpfile.js looks something like:

var uglify = require('gulp-uglify');
const html2js = () => {
     var source = gulp.src(config.appFiles.templates);
    return source
        .pipe(concat('templates-app.js'))
        .pipe(uglify())
        .pipe(gulp.dest(config.buildDir));
};

You can however use the gulp-terser package, which is very easy to just replace and get the same functionality:

var terser = require('gulp-terser');
const html2js = () => {
     var source = gulp.src(config.appFiles.templates);
    return source
        .pipe(concat('templates-app.js'))
        .pipe(terser())
        .pipe(gulp.dest(config.buildDir));
};

Using gulp-uglify-es instead of gulp-uglify helped me perfectly to accomplish same as you're asking for

The current (Nov 2021) easiest way to transpile and uglify is to use gulp-terser.

If you're already using gulp-uglify then just install gulp-terser and change "uglify" with "terser" and you're done.

const uglifyes = require('terser');

gulp.task('compress', function () {
    return gulp.src('src/*.js')
    .pipe(terser())
    .pipe(gulp.dest('dist'))
});
module.exports = {
  ...
  optimization: {
    minimize: true
  },
  ...
}

webpack can do the job

Related