March 28, 2016

With all of the hullabaloo in the Drupal community over integrating a JavaScript framework into core, I've felt it a great opportunity to revisit the basics of the language. Knowing "enough" JavaScript, I hadn't looked at a recent primer in a bit, and boy did I learn a lot. I had been hearing about ES6/2015 for a while, had seen it in all my build tool packages, but wasn't actually using it.

Babel and ES2015

It turns out, the enhancements to the language aren't terribly complicated and add a ton of power to your JavaScript!.

Getting started writing ES2015 in your theme: Babel

I hope you're using Gulp, but there's also a Babel package for Grunt as well. Babel is a JS transpiler that will let us write ES2015 code, and transpile it to ES5 code our browser will understand. Think of it as the PostCSS to your JS.

We'll just need to add two packages to our build process, Babel and a Babel preset.

$ npm i --save-dev gulp-babel babel-preset-es2015

With that, we have the necessary packages to start writing ES2015 in our themes! Let's take a look at the Gulp task real quick.


gulp.task('scripts', function() {
  gulp.src('js/**/*.js')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(babel({ presets: ['es2015']}))
    .pipe(uglify())
    .pipe(rename({suffix: '.min'}))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('../js'));
});

This task should look pretty similar to your Sass task. I init plumber to catch errors in the CL, init some sourcemaps (because we are transpiling, these help with debugging). We then pipe in Babel using the ES2015 preset. We end it with a standard uglify and rename, so that our end code is compressed and named accordingly.

Nothing terribly complex and we're up-and-running with ES2015!

Our Favorite Features

Now that you can write some sweet ES2015 code, where should you start? One of my favorite new features is Arrows functions and lexical this.

Arrow functions & lexical this

Have you ever wrote function() { // sweet functional code }? Most of us have, and these empty functions sure take up a ton of space for not doing much! With arrow functions we can condense this to () => { // sweet functional code }. Much better! Arrow functions accept agruments, so anytime you would use an anonmyous function you can probably use an arrow function.


function(x,y) {
  return x + y;
}

(x,y) => {
  return x + y;
}

The other real nifty thing about arrow functions is how they maintain this. No longer do you have to bind your object to your function to maintain the proper this (ie this.myFunction.bind(this)). Arrow functions maintain the this from their environment. This means they can't be used as constructor functions, or functions in object literals that need to have proper this maintainence.

Clearer variable names

We now have let and const for better variables, instead of everything being a var! If a variable is a constant declare it with const. If it's going to mutate, declare with let. It's that simple, and adds a level of clarity into your code. Self-documenting code is awesome!


var javascript = 'Awesome!';

// becomes

const javascript = 'Awesome!';

var output = '';
output += 'Print me!';

// becomes

let output = '';
output += 'Print me!';

Native Modules

JavaScript modules have been around for a bit now, but with ES2015 a lot of that power gets incorporated into the language. Using a native export call, you can export and import your modular code throughout your application. One step closer to not needing requireJS!

Example taken from babeljs.io


// lib/math.js
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;

More reading

If you're interested in more ES2015 features, or digging deeper into JS, here are some awesome resources.

Conclusion

If anything, the talk around JS in the community has cemented the need to learn JS better. For that, I'm very thankful, and can confidently declare that Chapter Three has fully adopted ES2015 and is excited to help move the JS and Drupal community forward!