53

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?

Don
  • 3,876
  • 10
  • 47
  • 76

9 Answers9

58

You can leverage gulp-babel as such...

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

gulp.task('minify', () => {
  return gulp.src('src/**/*.js')
    .pipe(babel({
      presets: ['es2015']
    }))
    .pipe(uglify())
    // [...]
});

This will transpile your es6 early in the pipeline and churn out as widely supported "plain" javascript by the time you minify.


May be important to note - as pointed out in comments - the core babel compiler ships as a peer dependency in this plugin. In case the core lib is not being pulled down via another dep in your repo, ensure this is installed on your end.

Looking at the peer dependency in gulp-babel the author is specifying @babel/core (7.x). Though, the slightly older babel-core (6.x) will work as well. My guess is the author (who is the same for both projects) is in the midsts of reorganizing their module naming. Either way, both npm installation endpoints point to https://github.com/babel/babel/tree/master/packages/babel-core, so you'll be fine with either of the following...

npm install babel-core --save-dev

or

npm install @babel/core --save-dev
scniro
  • 16,844
  • 8
  • 62
  • 106
  • 1
    You might also need to install babel-core, to do this run npm install --save-dev babel-core – rhysclay Jan 11 '18 at 04:17
  • 1
    @rhysclay Thanks for pointing this out! I actually never noticed this may happen - I thought it just came down with it. I researched what is going on a little bit and found a bit of interesting info. I've edited my answer if you'd like to check out what I found. – scniro Jan 11 '18 at 13:36
  • 1
    This didn't work for me. Recent solution is here https://stackoverflow.com/questions/38886840/how-to-solve-this-minification-error-on-gulp – Abk Dec 23 '18 at 08:24
  • How do I pass javascript as a string? Would that be possible? – Amanda Oct 19 '20 at 07:11
45

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

KayakinKoder
  • 3,243
  • 3
  • 23
  • 37
  • What ultimately worked for me was upgrading the whole gulp-* stack (except for gulp-useref that changed its API). Basically, removed all gulp-* dependencies from package.js and installed them from scratch. – Maksym May 18 '18 at 17:16
  • Will this then break the js for IE11? – Taylor A. Leach Aug 16 '18 at 16:39
  • @TaylorA.Leach yes, IE11 hasn't been supported for 2+ years. If you want to support IE11, you can't use (most features of) ES6. – KayakinKoder Aug 16 '18 at 19:49
  • Is this missing a step? I get "Error: Cannot find module 'uglify-es'". Googling, I also see that 'uglify-es' has been abandoned... – Phil Gyford Dec 03 '18 at 16:33
  • 1
    @PhilGyford yes, as your error messages states you need to install the uglify-es package. `yarn add uglify-es` should do that. It does look like uglify-es is going to be deprecated soon so I'll update this with a new package when I get a chance, but uglify-es is still downloaded 2.4 million times a week so it will likely be a long time until everyone moves to `terser` – KayakinKoder Dec 03 '18 at 17:58
  • That's stright to the point. Thanks. And for the one that need to support any old browsers, then transpile and use gulp-uglify. – Mohamed Allal Mar 25 '19 at 00:23
  • Install `gulp-terser` package and use same way that old _gulp-uglify_ – Pablo Fébolo May 12 '19 at 18:51
27

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'));
});
Vladimir Jovanović
  • 3,288
  • 1
  • 20
  • 27
  • 1
    Thanks very much. I wasted hours trying to install and use babel - the number of incompatible combinations with that product end es6 is incredible - babel is the biggest load of junk i've come across in gulp - everything else just works in gulp - but babel has been nothing but a nightmare with incompatibilities. – john blair Jun 02 '20 at 14:03
  • @johnblair - I've used it successfully for over a year. I recommend re-investigating. It can save a ton of time. I have a fairly complex setup too and it simplifies things a ton. – dgo Jul 09 '20 at 21:34
7

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'))
});
3

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));
};
kumaheiyama
  • 704
  • 1
  • 13
  • 28
2

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

Alena Levina
  • 103
  • 1
  • 8
2

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'))
});
gillytech
  • 3,595
  • 2
  • 27
  • 44
1

unfortunately, as per now, you can't use uglify with es-next code, you can:

  1. Transpile to ES5using Babel
  2. Use Babili instead of Uglify.
Hitmands
  • 13,491
  • 4
  • 34
  • 69
0
module.exports = {
  ...
  optimization: {
    minimize: true
  },
  ...
}

webpack can do the job

Giggs
  • 851
  • 10
  • 16