Getting started with Ionic 1 and ES6

For some context: When working on front end stuff, I’ve always written pure javascript with the exception of a few one off coffee script fixes. I’m super stoked about ES6 and have been converting many of my js heavy projects to use some of the ES6 syntax. Most recently I’ve been working on an app called Pushbit for competing with friends for weekly pushup count. It’s written using the ionic framework and I’ve built much of it using some cool new ES6 syntax and would love to share my build process.

Here’s how I got started (follow along on github: w1zeman1p/es6demo)

ionic start es6demo
cd es6demo

We’ll need to transpile our es6 code into es5 code for it to work on all current browsers including the phones. I’ve chosen to create a directory called jssrc at the root level of the app to store all my javascript code. The transpiled file will end up in www/js.

mkdir jssrc
mv www/js/* jssrc/

Luckily, ionic comes with a nice gulpfile that we can add to. I like gulp, and incase you enjoy a different flavor of build system you should checkout Addy Osmani’s list of https://github.com/addyosmani/es6-tools es6 tools. The idea here is that we want to some npm modules to read our es6 code and output a single concatenated es5 javascript file. We’ll use 3 new npm modules which you might need to install using these commands:

npm install gulp-traceur
npm install gulp-sourcemaps
npm install gulp-watch
npm install gulp-concat

Here’s a snippet to get you started:

//gulpfile.js
var gulp = require('gulp'),
  concat = require('gulp-concat'),
  sourcemaps = require('gulp-sourcemaps'),
  traceur = require('gulp-traceur'),
  watch = require('gulp-watch');

var paths = {
  scripts: ['./jssrc/**/*.js']
};

gulp.task('scripts', function () {
  return gulp.src(paths.scripts)
    .pipe(sourcemaps.init())
    .pipe(traceur())
    .pipe(concat('all.js'))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./www/js'));
});

gulp.task('default', ['scripts']);

gulp.task('watch', function () {
  gulp.watch(paths.scripts, ['scripts']);
});

Lets go through this and talk about each piece.

First we need to require the modules we’ll use for transpiling. I’ve tried gulp-traceur and gulp-6to5 which are both gulp packages that overlay Traceur and 6to5 respectively. Traceur is a project out of google and seems to have the most traction at the moment. It also was the tool that worked best for me. gulp-sourcemaps is used to build a sourcemap file that can be used by the browser during debugging to show you the original code, rather than the transpiled es5. gulp-watch is handy for constantly running your gulp task when your es5 files change.

sourcemaps = require('gulp-sourcemaps'),
traceur = require('gulp-traceur'),

I’ve added scripts: [‘./jssrc/**/*.js’] to the given paths variable.

The scripts task will be used to convert our scripts. First it reads the files in paths.scripts, then initializes sourcemaps, then runs the files through traceur, then concatenates them into a file called all.js, then drops that file into www/js.

gulp.task('scripts', function () {
  return gulp.src(paths.scripts)
    .pipe(sourcemaps.init())
    .pipe(traceur())
    .pipe(concat('all.js'))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./www/js'));
});

Now that our gulpfile is all good to go we can run gulp and gulp watch which will start listening to changes in our javascript files.

gulp
gulp watch

Lets checkout the www/index.html file and make sure we’re including the new transpiles all.js file.

There is an autogenerated section that looks like this:

<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>

Update that to reference all.js.

<!-- your app's js -->
<script src="js/all.js"></script>

We also need to add in a few special files referenced here: https://code.google.com/p/traceur-compiler/wiki/GettingStarted that will allow us to run traceur compiled js files in the browser.

Add these scripts to your index.html head:

<script src="https://traceur-compiler.googlecode.com/git/bin/traceur.js"></script>
<script src="https://traceur-compiler.googlecode.com/git/src/bootstrap.js"></script>

Lets fire up the server and see the result.

ionic serve

See the default app in the browser? Cool!

Lets get to writing some ES6 to test it out. Open up jssrc/app.js. First I like to go through and convert all anonymous function arguments to the () => {} syntax. something like this:

// ... OLD
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
  .run(function($ionicPlatform) {
    $ionicPlatform.ready(function() {

// ... NEW!
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
  .run(($ionicPlatform) => {
    $ionicPlatform.ready(() => {

Refresh the page and all should be well.

Lets try something a little more interesting. Add the following snippet at the bottom of jssrc/app.js:

class Snowman {
  constructor (name) {
    this.name = name;
  }

  sayHi() {
    console.log("Hi! I'm " + this.name + " and I like warm hugs.");
  }
}

var olaf = new Snowman('Olaf');
olaf.sayHi();

Open the dev console (cmd+opt+i), then refresh and observe the message from the instance of our es6 class.

That should get you started. In a following post I’ll show you how I built out my angular model layer with influences from my backbone.js experience.