80

I am trying to use gulp in order to minify a folder containing JS files. However, one of the files has the above error, preventing it from being minified.

I managed to catch and print the error, which I've partially printed here:

JS_Parse_Error {
 message: 'SyntaxError: Unexpected token: punc ())',
 filename: 'ex.js',
 line: 189,
 col: 25,
 pos: 6482,
 stack: Error\n    at new JS_Parse_Error (eval at <anonymous> ... ) 
 plugin: 'gulp-uglify',
 fileName: '.../js/ex.js',
 showStack: false
}

The file in question contains the following, shortened:

function() {
  ...
  $.confirm({
    buttons: {
        confirm: function() {
            $.post('/ajax-handler', {
                    ...
                })
                .done( function(response) {
                    var data = filterResponse(response);
                    if (data['status'] == 'success') {
                        sleep(1000).then(() => {
                    *       ...
                        });
                        sleep(5000).then(() => {
                            ...  
                        });

                    } else {
                        console.log('Oops!');
                    }
                })
                .fail( function(err, status, response) {
                    ...
            });
        },
        cancel: function() {}
    }
 });
  ...
}

I added the "*" above in order to indicate the exact position listed by JS_Parse_Error.

Alexander
  • 999
  • 1
  • 9
  • 18
  • 10
    Looks like you're not converting the code to ES5 before minifying, so uglify doesn't understand what `() => {}` means. If you change it to `sleep(1000).then(function() { ... })` it should work unless there are other errors – Lucas Feb 21 '17 at 18:46
  • Alright, had to sort out a couple other errors, but that definitely helped and everything's working now. For the record, since I've been seeing it thrown around a lot, would you know what the difference is between ES5 and ES6? – Alexander Feb 21 '17 at 19:07
  • 1
    you can check http://es6-features.org/. There are lots of differences – Lucas Feb 21 '17 at 19:10
  • 1
    @Alexander I have an npm package that exhibits this error, how come it is not converted to ES5 since the rest of the project is being converted? – Qwerty Apr 27 '17 at 09:20
  • @Qwerty I'll admit, it's hard for me to tell without knowing more about what you're trying to minify, unfortunately. In my case above I had to manually change the code to ES5. – Alexander Apr 27 '17 at 14:54
  • I believe I am minifyinf everything. I write my project in ES6, I use some npm packages and some are in ES6 as well - those exhibit these UglifyJS errors. I was wondering why my code is transpiled and minified without problems, but those packages are not. Maybe another transpiler got my code into ES5 disregarding modules, then there was a mess of ES5+ES6 code and UglifyJS got mad. Anwyay, I have solved it. I taught UglifyJS ES6. – Qwerty Apr 28 '17 at 07:42

8 Answers8

67

// Update

From the comments ~ @imolit

 v2.0.0 (2018-09-14) - BREAKING CHANGES (link)

Switch back to uglify-js (uglify-es is abandoned, if you need uglify ES6 code please use terser-webpack-plugin).


Original answer before the update...

I hope you can get inspired by this solution which works with webpack. (link below)

Simply teach UglifyJS ES6

There are two versions of UglifyJS - ES5 and ES6 (Harmony), see on git
ES5 version comes by default with all the plugins, but if you install a Harmony version explicitly, those plugins will use it instead.

package.json

"uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony"

or

npm install --save uglify-js@github:mishoo/UglifyJS2#harmony

yarn add git://github.com/mishoo/UglifyJS2#harmony --dev

Webpack

To use it with webpack install also the webpack plugin

npm install uglifyjs-webpack-plugin --save-dev

yarn add uglifyjs-webpack-plugin --dev

then import the manually installed plugin

var UglifyJSPlugin = require('uglifyjs-webpack-plugin');

and replace it in code

-  new webpack.optimize.UglifyJsPlugin({ ... })
+  new UglifyJSPlugin({ ... })

For more webpack info (Installation/Usage) see https://github.com/webpack-contrib/uglifyjs-webpack-plugin#install

Qwerty
  • 29,062
  • 22
  • 108
  • 136
  • Hi, how to use it in webpack? I have this in my prod pipeline `new webpack.optimize.UglifyJsPlugin()` and after installing the harmony version I still get the "punct()" errors. ta – Skorunka František May 21 '17 at 16:39
  • @SkorunkaFrantišek You replace `new webpack.optimize.UglifyJsPlugin()` with `new UglifyJSPlugin()`. Don't forget to import `var UglifyJSPlugin = require('uglifyjs-webpack-plugin');` The webpack's included plugin is the old one, this is how you explicitly tell to use the one you installed. – Qwerty May 23 '17 at 09:10
  • Yes, that helped! Thank you. – Skorunka František May 23 '17 at 14:55
  • 4
    Just a heads up, this solution does not work as is, as later versions of uglifyjs-webpack-plugin aren't compatible with the uglifyjs2#harmony branch. For uglify-webpack-plugin, I had to use v0.4.4. For uglify-js, I used git://github.com/mishoo/UglifyJS2#harmony-v2.8.22. Hope that helps somebody – Exponent Jul 26 '17 at 21:34
  • 4
    FYI, this is fixed in the beta of uglifyjs-webpack-plugin. Use `"uglifyjs-webpack-plugin": "^1.0.0-beta.2"` in your package.json to get it working again with the fix above. – sschueller Aug 02 '17 at 08:42
  • 4
    Wouldn't `--save-dev` be more fitting in this case? – adi518 Aug 09 '17 at 08:39
  • Thanks, solved it by uglifyjs-webpack-plugin@1.0.0-beta.1, by the way, i found uglifyjs-webpack-plugin@1.0.0-beta.2 may throw some errors, so just downgrade to 1.0.0-beta.1. – liyj144 Sep 08 '17 at 03:34
  • 2
    N.B: The Webpack section is outdated. `uglifyjs-webpack-plugin` [no longer supports ES6](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/blob/master/CHANGELOG.md#200-2018-09-14) and they recommend the [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) instead. – imolit Dec 12 '18 at 16:48
  • @imolit Thanks for the heads up. I updated the answer a little, but due to my lack of context, I would like to ask you to edit in some details. I put a placeholder for you there ;) – Qwerty Dec 13 '18 at 20:19
  • Not sure what you'd like me to update. I temporarily solved the problem with parsing ES6 by running `yarn add uglifyjs-webpack-plugin@1.3.0 --dev`, which does include support for ES6. I think the *correct* approach would be to install the terser-plugin, but since I haven't tried it, I cannot recommend it. Also, all this assumes that people are running webpack, while the question was related to gulp which may not necessarily involve webpack. – imolit Dec 14 '18 at 20:11
17

npm install uglifyjs-webpack-plugin --save-dev is not enough

The main problem is "uglifyjs-webpack-plugin": "^0.4.6" in webpack's package.json

According to semver, ^0.4.6 := >=0.4.6 <0.5.0. Because of the leading zero, webpack will never use the 1.0.0-beta.2.

So after running npm i -D uglifyjs-webpack-plugin@beta, you need to do one more step which is rm -rf node_modules/webpack/node_modules/uglifyjs-webpack-plugin. Then webpack will pick up the version from node_modules/uglifyjs-webpack-plugin instead of node_modules/webpack/node_modules/uglifyjs-webpack-plugin

Update on 2018-04-18: webpack v4 does not have this issue

ATNASGDWNGTH
  • 876
  • 11
  • 26
8

Add the babel-preset-es2015 dependency to fix this.

And also add 'es2015' in .babelrc file.

json
{
    "presets": ["es2015"]
}
MatejMecka
  • 1,448
  • 2
  • 24
  • 37
Qing
  • 3,029
  • 7
  • 25
  • 31
6

If you got this error using Grunt (grunt-contrib-uglify) the solution is to install ES6 version of the plugin:

npm install grunt-contrib-uglify-es --save-dev
amicoderozer
  • 2,046
  • 6
  • 28
  • 44
5

I am having the same issue, i found a great answers here that helped me to reach the the file that was causing the error.

Go to Rails Console and Paste:

JS_PATH = "app/assets/javascripts/**/*.js";
Dir[JS_PATH].each do |file_name|
  puts "\n#{file_name}"
  puts Uglifier.compile(File.read(file_name))
end

Hope it helps someone!

Hamza Khan
  • 1,321
  • 11
  • 15
3

For me it had nothing to do with Uglify not working correctly, but rather a dependency (in this case empty-promise) that has not been compiled to ES5 yet. As we just imported the raw source file, but babel is only transpiling files outside of node_modules, uglify got confused by the ES6 syntax.

Simply check if any dependency you've recently added might not have a "dist" build.

spaceemotion
  • 1,404
  • 4
  • 24
  • 32
  • How to check if a dependency has a dist-build? – Grim Feb 19 '19 at 09:50
  • @PeterRader packages usually have a `dist` folder (or something similar) under their directory in `node_modules`. Just look if the index file in their `package.json` points to a compiled source directory. If not, you need to add them to your babel config. – spaceemotion Feb 22 '19 at 14:10
0

Add stage-3 to presets in .babelrc file.

{
  "presets": [
    "stage-3"
  ]
}
Cong Nguyen
  • 3,199
  • 1
  • 23
  • 22
0

enter image description here

hello, The problem is that other methods do not start with window. This is how I solved it. I got this error after putting if statement. To solve the problem, I called the fbAsyncInit method with "window" prefix.

window.fbAsyncInit = function()

it fixed it.