Thursday, April 3, 2014

Use GruntJs to Uglify ES6 Application

Get to know how to Uglify (mangling and minify) your javascript files written in javascript ES6.

Currently grunt-contrib-uglify has not yet supported ES6 syntax, therefore we need to find a way to transpile the ES6 code file to ES5 code file.

Although it’s no point uglify server-side javascript code, we will use Koa application for demo purpose and this should work for client-side script as well. We will lint the javascript file, transpile it, then uglify it.

Install modules

Back to TOC
Run the commands to install required modules.

npm init

npm install --save-dev grunt grunt-contrib-jshint grunt-contrib-uglify grunt-regenerator grunt-es6-transpiler load-grunt-tasks grunt-contrib-watch git+https://github.com/Zev23/grunt-express-server.git

npm install --save koa
Module Description
grunt-contrib-jshint Javascript linter
grunt-es6-transpiler Transpile ES6 code to ES5
grunt-regenerator Facebook’s Regenerator to properly transpile generator function.
grunt-express-server To start a express server. I have forked the project and add capability to run Koa server.
load-grunt-tasks Convenient grunt task module loader

The Application (app.js)

Back to TOC

//app.js
"use strict";

const
  app = require("koa")(),
  port = 3000;

//Logger
app.use(function *(next){
  let start = new Date();
  yield next;
  let ms = new Date() - start;
  console.log("%s %s - %s", this.method, this.url, ms);
});

app.use(function *(){
  this.body = "Hello World";
});

app.listen(port, function() {
  console.log("Server listening at %s", port);
});

The script file uses ES6 features such as generator and let.


gruntfile.js

Back to TOC

module.exports = function(grunt){
  "use strict";

  require("load-grunt-tasks")(grunt);

  grunt.initConfig({
    express: {
      svr:{
        options : {
          script: "./app.min.js",
          opts: ["--harmony"]
        }
      }
    },

    jshint: {
      files: ["app.js"],
      options: {
        "curly": true,
        "eqeqeq": true,
        "undef": true,
        "unused": "vars",
        "esnext":true,
        "devel":true,
        "node":true,
        "noyield":true
      }
    },

    es6transpiler: {
      dist: {
        files: {
          "app.trans.js": "app.js"
        }
      }
    },

    regenerator: {
      options: {
        includeRuntime: true
      },
      dist: {
        files: {
          "app.es5.js": "app.trans.js"
        }
      }
    },


    uglify: {
      main: {
        files: {
          "app.min.js":["app.es5.js"]
        }
      },
      options: {
        mangle:{toplevel:true},
        sourceMap: true,
        sourceMapName: "app.js.map",
        sourceMapIncludeSources: true,
        compress:true
      }
    },

    watch: {
      all: {
        files:["app.js"],
        tasks:["jshint","es6transpiler","regenerator","uglify", "express:svr"],
        options:{
          spawn:false
        }
      }
    }

  });


  grunt.registerTask("default", ["jshint","es6transpiler","regenerator","uglify", "express:svr", "watch"]);

};
  1. First we load all the grunt tasks module using load-grunt-tasks.
  2. Then we initConfig those tasks:
    • express: From grunt-express-server, this will configure start the server from grunt.
    • jshint: Lint javascript file. For server-side and ES6 code, few options must be enabled:
      • esnext: To check ES6 syntax
      • devel: To suppress message on globals like “console”.
      • node: To suppress node server globals like “require”.
      • noyield: To allow generator function without yield.
    • es6transpiler: Transpile ES6 code to ES5 code. Till this stage the transpile of generator is not working. Generator syntax function *() still can be seen and UglifyJS won’t work with it.
    • regenerator: Base on above issue, Regenerator is used to overcome it.
    • uglify: Mangle and minify the script file.
    • watch: Restart server when app.js changed. The tasks will rerun everything from jshint till server restart.
  3. Register default task.

Run grunt

Back to TOC

Run the application.

grunt

You can run individual task as well:

Command Description
grunt jshint Run linter to check app.js
grunt es6transpiler Transpile and output app.trans.js
grunt regenerator Input: app.trans.js. Output: app.es5.js
grunt uglify Input: app.es5.js. Output: app.min.js
grunt express:svr Start the server

The bottom line is UglifyJS cannot accept ES6 code file as input yet. Therefore if it can successfully compiled, then we got ES6 code file successfully transpiled.







Copyright © Zev23.com 2014 All Rights Reserved. No part of this website may be reproduced without Zev23.com’s express consent.

No comments: