Digiguru.co.uk

The holy grail of javascript loaders

03 Mar 2015

Reading time: 1 minute

So I’ve been watching the world of module loaders in javascript over the past few year, too nervous to jump in to either CommonJS or RequireJS in fear of getting it wrong.

Just as we started to feel like making the jump, ES6 modules seemed to take the world by storm, offering a fresh new and elegant solution. The fear is - es6 modules are not baked into the browsers yet, so is it too risky to jump into ES6 already?

My answer is no! The reason I can confidently start looking into es6 is because I know there are tools out there that can help me during the transition. Many projects are looking into creating ES6 transpilers that take ES6 as a source and output raw javascript for backwards compatibility. Projects like the es6 module transpiler are a perfect example.

Here is a very simple ES6 module.

export var test = 'Hello';
export class MyClass {
  constructor() {
    console.log('ES6 Class!');
  }
};

If I drop that into a folder with the following gruntfile…

module.exports = function(grunt) {

  grunt.initConfig({
     transpile: {
        cjs: {
          type: "cjs", // or "amd" or "yui"
          files: [{
            expand: true,
            src: ['**/*.js'],
            dest: 'output/cjs/'
          }]
        },
        amd: {
          type: "amd", // or "amd" or "yui"
          files: [{
            expand: true,
            src: ['**/*.js'],
            dest: 'output/amd/'
          }]
        }
    }
  });

  grunt.loadNpmTasks('grunt-es6-module-transpiler');

  grunt.registerTask('default', ['transpile:amd','transpile:cjs']);

};

(Of course I have to make sure I have grunt instaleld along with the relevant plugin

$ npm install -g grunt-cli
$ npm install grunt-es6-module-transpiler --save-dev

Now I just run the grunt task…

$ grunt

And voila - it outputs some beutiful module code in both AMD and CommonJS…

// amd/app.js
define("example", 
  ["exports"],
  function(__exports__) {
    "use strict";
    var test = 'Hello';
    __exports__.test = test;export class MyClass {
      constructor() {
        console.log('ES6 Class!');
      }
    };
  });


// cjs/app.js
"use strict";
var test = 'Hello';
exports.test = test;export class MyClass {
  constructor() {
    console.log('ES6 Class!');
  }
};

Nice! Now I can defer the decision until later.