Get ready for ECMAScript 6

JavaScript evolves, and the next 6th version will be awesome, we’ll have many great things like classes, maps, modules, … (probably much more, but I’m just starting to learn). There are several ways to begin writing ES6 source code (even now with shims, polyfills and transpilers), you can find a tools list here https://github.com/addyosmani/es6-tools.

I chose the simplest method to begin (to my mind) : no grunt task to transpile ES6 to ES5 or ES3, just some shims in the browser. But you’ll still need a web server (http server). Personally I use a node script with Express, but other solution should be good like python command python -m SimpleHTTPServer.

PS: you need bower for install shims. (and node and npm of course).

Caution: I try to improve my english, I hope this post will be understandable, but don’t hesitate to correct me (please).

Prepare the project

In a directory (ie: es6-project) create 4 files:

  • .bowerrc
  • bower.json
  • package.json (to declare Express dependencies)
  • app.js (our http server)

with these contents:

.bowerrc

{
  "directory": "public/bower_components"
}

bower.json

{
  "name": "es6-project",
  "version": "0.0.0",
  "dependencies": {
    "uikit": "~2.8.0",
    "es6-module-loader": "~0.6.1",
    "jquery": "~2.1.1",
    "es6-shim": "~0.13.0"
  },
  "resolutions": {
    "jquery": "~2.1.1"
  }
}

Remark: uikit isn’t mandatory, it is only for pretty pages.

package.json

{
  "name": "es6-project",
  "description" : "es6-project",
  "version": "0.0.0",
  "dependencies": {
    "express": "4.1.x",
    "body-parser": "1.0.2"
  }
}

app.js

var express = require('express')
  , http = require('http')
  , bodyParser = require('body-parser')
  , app = express()
  , http_port = 3000;

app.use(express.static(__dirname + '/public'));
app.use(bodyParser());

app.listen(http_port);
console.log("Listening on " + http_port);

And now install all of this!

  • to download es6 shims: type bower install
  • to install Express: type npm install

That’s all. Now, you should have something like this:

es6-project/
β”œβ”€β”€ node_modules/
β”œβ”€β”€ public/   
|   └─── bower_components/     
β”œβ”€β”€ .bowerrc
β”œβ”€β”€ bower.json
β”œβ”€β”€ package.json    
└── app.js

Create a js directory, with an app sub-directory in public, and a main.js file in app directory and an index.html file in public:

es6-project/
β”œβ”€β”€ node_modules/
β”œβ”€β”€ public/   
|   β”œβ”€β”€ bower_components/  
|   β”œβ”€β”€ js/          
|   |   └── app/
|   |        └── main.js
|   └── index.html
β”œβ”€β”€ .bowerrc
β”œβ”€β”€ bower.json
β”œβ”€β”€ package.json    
└── app.js

Some code

# Prepare html

Modifiy index.html like that:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>es6-project</title>
  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
  <link rel="icon" sizes="196x196" href="html5.png">
  <meta name="mobile-web-app-capable" content="yes">
  <link rel="stylesheet" href="bower_components/uikit/dist/css/uikit.almost-flat.min.css" />
</head>

<body style="padding: 20px">
  <h1></h1>

  <script src="bower_components/jquery/dist/jquery.min.js"></script>
  <script src="bower_components/traceur/traceur.js"></script>
  <script src="bower_components/es6-module-loader/dist/es6-module-loader.min.js"></script>
  <script src="bower_components/es6-shim/es6-shim.min.js"></script>

</body>
</html>

# Application class

We are going to write our first ES6 class. So in the main.js file, type this content:

class Application {

  constructor () {
    $("h1").html("E6 rocks!")
  }

}

$(() => {
  new Application();
});

This is our main class, the first β€œthing” that will be run in our webapp.

# β€œIgnition”

We need to declare our main class in index.html, just add this after scripts declarations:

<script>
  System.import('js/app/main');
</script>

So, your index.html should look like to this:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>es6-project</title>
  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
  <link rel="icon" sizes="196x196" href="html5.png">
  <meta name="mobile-web-app-capable" content="yes">
  <link rel="stylesheet" href="bower_components/uikit/dist/css/uikit.almost-flat.min.css" />
</head>

<body style="padding: 20px">
  <h1></h1>

  <script src="bower_components/jquery/dist/jquery.min.js"></script>
  <script src="bower_components/traceur/traceur.js"></script>
  <script src="bower_components/es6-module-loader/dist/es6-module-loader.min.js"></script>
  <script src="bower_components/es6-shim/es6-shim.min.js"></script>

  <script>
    System.import('js/app/main');
  </script>
</body>
</html>

You can now check that everything works:

Hopefully, you shoul obtain a β€œvery nice” message E6 rocks!.

Now you have a β€œrunning” project and you can go deeper.

Go deeper: more classes

Create a models directory in publix/js/app with two new JavaScript files inside human.js and humans.js:

es6-project/
β”œβ”€β”€ node_modules/
β”œβ”€β”€ public/   
|   β”œβ”€β”€ bower_components/  
|   β”œβ”€β”€ js/          
|   |   └── app/
|   |        β”œβ”€β”€ models/
|   |        |   β”œβ”€β”€ human.js    
|   |        |   └── humans.js   
|   |        └── main.js
|   └── index.html
β”œβ”€β”€ .bowerrc
β”œβ”€β”€ bower.json
β”œβ”€β”€ package.json    
└── app.js

Human class

Imagine Human class as a kind of model:

class Human {

  constructor (args) {
    this.id = args.id;
    this.firstName = args.firstName;
    this.lastName = args.lastName;
  }
}

export default Human;

export keyword is very important, we β€œexpose” Human class, so we can declare/load it from other JavaScript files.

Humans class

We could say that Humans class is a collection of human’s models:

class Humans {

  constructor () {
    this.models = [];
  }

  add (human) {
    this.models.push(human);
  }
}

export default Humans;

Using Human and Humans in Application class

We need to declare our 2 classes to use them. You have to use import keyword:

import Human from './models/human';
import Humans from './models/humans';

And now, you can instantiate models and collections:

var bob = new Human({id: 1, firstName:'Bob', lastName:'Morane'});
var john = new Human({id: 2, firstName:'John', lastName:'Doe'});

var humans = new Humans();

humans.add(bob);
humans.add(john);

And if you want to display the collection content, before add <ul></ul> in the body of index.html and write this JavaScript code to populate the list (<ul></ul>):

$("ul").html(humans.models.reduce(function(previous, current) {
  return previous + `
    <li>${current.id} ${current.firstName} ${current.lastName}</li>
  `;
},""));

Remark:String interpolation (as with Coffeescript) is a very handy feature of ES6, note the use of the symbol ` (back ticks) instead of double or single quotes to declare a β€œtemplate string”.

So at the end, you Application should look like this:

import Human from './models/human';
import Humans from './models/humans';

class Application {

  constructor () {
    $("h1").html("E6 rocks!")

    var bob = new Human({id: 1, firstName:'Bob', lastName:'Morane'});
    var john = new Human({id: 2, firstName:'John', lastName:'Doe'});

    var humans = new Humans();

    humans.add(bob);
    humans.add(john);

    $("ul").html(humans.models.reduce((previous, current) => {
      return previous + `
        <li>${current.id} ${current.firstName} ${current.lastName}</li>
      `;
    },""));

  }
}

$(() => {
  new Application();
});

You have now a functional ECMAScript 6 project, you can play!

blog comments powered by Disqus

Related posts