Search code examples
javascriptclassecmascript-6uglifyjs2

uglifyjs a javascript class - unexpected token error


I'm trying to write some new javascript using classes and I'm getting an "'Unexpected token: name (Utils)'" error when trying to minify the piece of code with uglifyjs2.

Here is my class

'use strict';

class Utils {
    // Constructor
    constructor() {
        marvin.Utils = Utils;
    }

    // Build a Form
    buildForm(keys) {
        var args = Array.prototype.slice.call(arguments, 1);
        var form = {};
        keys.forEach(function(index,key) {
            form[key] = args[index];
        });
        return form;
    }

    // Unique values
    unique(data) {
        return new Set(data);
    }
}

When trying to minify with uglifyjs, I get the following error

'Unexpected token: name (Utils)',

which corresponds to the U in the first line, "class Utils {".

I know there seem to be some issues with uglifyjs2 minifying the new ES6 standards but I don't know if that's the problem, or just some syntax thing I'm missing. I've tried uglifyjs2 and grunt-contrib-uglify and I get the same error.

If it is an ES6 problem, does anyone know of a solution available on how to properly minify the new JS class? I've tried using Babel (grunt-babel) in my grunt to transpile my code from ES6 to ES5, but that didn't actually change the code structure at all. What is the equivalent form of a class in ES5? This is my post-transpiled code.

Update

Ok. So I didn't have the correct Babel presets and plugins installed and loaded in my Gruntfile. So I installed them, but it's still not working. During Babel runtime, I'm getting the error

Running "babel" task

Running "babel:dist" (babel) task
Verifying property babel.dist exists in config...OK
Files: js/es6/utils.js -> js/es6/utils.new.js
Options: sourceRoot="etc/", sourceMap=false, presets=["babel-preset-es2015"], plugins=["babel-plugin-transform-es2015-classes"]
Warning: Unknown plugin "babel-plugin-transform-es2015-classes" specified in "base" at 0, attempted to resolve relative to "js/es6" Use --force to continue.

Here is my Gruntfile config. I have my node_modules and gruntfile somewhere else than where my application source files are.

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // Babel - transpiler from ES6 to ES5
    babel: {
        options: {
            sourceRoot: 'etc/',
            sourceMap: false,
            presets: ['babel-preset-es2015'],
            plugins: ["babel-plugin-transform-es2015-classes"]
        },
        dist: {
          files: [{
            expand: true,
            src: ['js/es6/*.js'],
            ext: '.new.js'
          }]
        }
    }
  });
// Set default file path
  grunt.file.setBase('../python/marvin/web/static/');

My application tree looks like this, and I'm running grunt inside the etc/ directory. All my javascript files are inside the js subdirectory many levels down.

  • trunk/
    • etc/
      • node_modules/
      • Gruntfile.js
      • package.json
    • python/
      • marvin/
        • web/
          • static/
            • js/
              • es6/
                • utils.js
            • css/

How can I tell the babel config that my presets/plugins are in one directory, but my javascript files are in another?


Solution

  • Well, I solved it by restructuring my directory system to be more in line with the other examples I've seen. Basically with my Gruntfile, package.json, and node_modules in the same directory level as my source files. Here is my new structure...

    • trunk/
      • etc/
      • python/
        • marvin/
          • web/
            • static/
              • js/
              • css/
              • src/
              • Gruntfile.js
              • package.json
              • node_modules/

    and my new Babel config in my Gruntfile file looks like

    babel: {
        options: {
            sourceMap: false,
            presets: ['es2015']
        },
        dist: {
          files: [{
            expand: true,
            cwd: 'src',
            src: ['**/*.js'],
            dest: 'js',
            ext: '.js'
          }]
        }
    }
    

    Everything transpiles correctly now, and I can properly minify with uglifyjs.