Ecmascript 6 Shim Versus Transpiler

ecmascript-6

npm install es6-shim
require('es6-shim')

<script src="path/to/es6-shim.js"></script>

To use the es6-shim, simply make sure that the shim file gets loaded before any 
scripts that depend on the ES6 features.

Shims are simpler and easier to work with, because we only need to include it in 
our page or node app before other scripts. However, a shim cannot support 
syntactic features. If we want those, we need a transpiler.

There are two ways to use Traceur:

1. Include Traceur compiler in your page/node
2. Pre-compile the code on the server

The first option is good for quickly testing things, but it comes with a 
performance hit. The JS code is compiled on the fly on the page, so it’s not as 
fast as running pre-compiled code. If we're planning on running ES6 code in the 
browser, we should use approach #2, but #1 is OK with nodejs.

npm install --save traceur

We have two typical scenarios for using ES6:

1. Load the whole app using ES6 modules, a typical case with new applications
2. Mix and match node modules and ES6 modules, a typical case with existing 
   applications.

If our app is written mostly in ES6, we will probably want to use this method.  
We can still use node’s own require loading with this if needed! The way this 
method works is we write an entry point for our application as a normal node 
module. In this entry point, we load an ES6 file, which bootstraps our 
application. First, let’s create the bootstrap file:

//bootstrap.js
export function run() {
  console.log('Hi there');
}

Next, create the entry point file. This is what we will run using node:

//app.js
var traceur = require('traceur');
traceur.require.makeDefault(function(file) {
  return file.indexOf('node_modules') == -1;
});

require('./bootstrap').run();

Now we can run the above code using node: node app.js

The second line of code makes traceur’s require override node’s own. We use a 
simple check against the file path to make sure we don’t run any files in 
node_modules through traceur, as it would serve no purpose. The beautiful part 
about this is that Traceur becomes essentially transparent: We can use node 
modules within ES6 modules, we can use require, etc.

We can use either require or ES6 module import syntax for this. For example, 
using require:

//bootstrap.js
var express = require('express');

export function run() {
  console.log('Hi there'); 
  var app = express();
}

Or, using ES6 module imports:

//bootstrap.js
import * as express from 'express';

export function run() {
  console.log('Hi there'); 
  var app = express();
}

Mixing and matching node modules and ES6 modules:

This approach can be used if you have an existing app where you want to start 
using ES6 modules. With this approach, we just include traceur within our 
module, and use the require function from it directly:

.require('./example.js');

//example.js is an ES6 module, we can use it from here as we'd normally use it:
example.whatever();

Traceur workflow for browsers:

In browser-land life isn’t as easy. We need to install the Traceur as a 
command-line tool, and need another file from it as well.

npm install -g traceur

We can now run it using traceur from the command-line. We will also need the 
traceur-runtime.js file. Once you’ve installed traceur, you can find it in your 
npm directory. This is typically located in /usr/local/lib/node_modules/traceur
/bin/traceur-runtime.js. Copy the file so that you can include it within the 
HTML page. If you can’t find the file, you can install traceur into a local 
node_modules using npm install traceur. Then, the file will be in the current 
dir, under node_modules/traceur/bin/traceur-runtime.js

Setting up an ES6 module on a web page:

Let’s assume a simple project structure, where source code files are placed in 
src/, and the build output will be in build/. The traceur-runtime file is 
assumed to be in lib/traceur-runtime.js First off, we’ll create a simple example 
file:

//src/app.js
export function run() {
  console.log('Hi there');
}

Next, we can use traceur to convert it into ES5: 

traceur --out build/bundle.js src/app.js 

Using the --out flag, we’re telling traceur to bundle all dependencies of our 
app.js script into the bundle.js file. Finally, the HTML:

<!DOCTYPE html>
<html>
  <head>
    <script src="lib/traceur-runtime.js"></script>
    <script src="build/bundle.js"></script>
    <script>
      var m = System.get('src/app.js');
      //m is our ES6 module, with all the exported things
      m.run();
    </script>
  </head>
  <body>
  </body>
</html>

We need to include the runtime and our bundle. Then, we use the ES6 System 
module loader to get access to the module, and call the run function we exported 
in it.

Using imports and other libraries:

If you’re building multiple ES6 modules, using them with this setup is simple:

//src/app.js
import * as foo from 'foo';
export function run() {
  console.log('Hi there');
}

You can import any ES6 modules as normal. Traceur will handle the dependencies, 
and will automatically bundle them into the output file. Using other libraries, 
such as jQuery, works exactly like it does when not using ES6:

<script src="path/to/jquery.js"></script>
<script src="lib/traceur-runtime.js"></script>
<script src="build/bundle.js"></script>
<script>
  var m = System.get('src/app.js');
  m.run();
</script>

//src/app.js
export function run() {
  $(() => {
    $(document.body).html('hello world');
  });
}

You simply include any libraries you want before your scripts, and the globals 
they provide will be available in your ES6 modules as well.

To enable source maps with node, npm install --save traceur-source-maps and 
include it in your script:

var traceur = require('traceur');
require('traceur-source-maps').install(traceur);

In the case of browsers, we just need to adjust the traceur command parameters 
a little bit: 

traceur --source-maps --out build/bundle.js src/app.js
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License