Skip to content

Instantly share code, notes, and snippets.

@passcod
Last active November 12, 2018 06:29
Show Gist options
  • Save passcod/80f70796cf042cbd5838 to your computer and use it in GitHub Desktop.
Save passcod/80f70796cf042cbd5838 to your computer and use it in GitHub Desktop.

ES6

The current version of JavaScript. We support "old" browsers, so we can't use it on the client side*, but we can totally use it server-side or in other environments where we have stricter control over the JS runtime.

ES6 has various new features:

'use strict'

Put it at the top of files to switch on "strict mode" which fixes various behaviours that have led developers over the ages to call JS "broken". For example, some comparisons, especially with NaN, undefined, and null; also disables the performance-hurting with keyword.

In Node v4 (previously io.js), 'use strict' enables some extra behaviour like:

const, let

These are variable declarations with different semantics than var. let is block-scoped, consts is block-scoped and cannot be redefined (if it's an array or an object, its inside can be modified, though). Generally you should use let everywhere you used var previously, except if you really want var semantics.

Template strings

In other languages, these are known as interpolated strings. PHP has "$foo", Ruby "#{foo}". ES6 has:

// Previously:
var url = base_url + "/auth";

// Now:
let url = `${base_url}/auth`;
() => {}

Arrow functions are a shorter syntax for lambdas aka "anonymous functions":

// Previously:
$.get(base_url + "/" + token + "/projects", function(response) {
  $('#result').text(response).addClass('success');
})

// Now:
$.get(`${base_url}/${token}/projects`, (response) => {
  $('#result').text(response).addClass('success');
})

They also have an even shorter syntax for functions that return their entire body:

// Previously:
[1, 2, 3].map(function (n) { return n * 2; })

// Now:
[1, 2, 3].map((n) => n * 2)

Most importantly, they have lexical this:

// Previously:
function SomeClass() {
  var self = this;
  self.BASE_URL = 'http://example.com';
  someInitialisation();

  self.method = function(urls) {
    return urls.map(function(url) {
      return self.BASE_URL + url;
    });
  };
}

// Slightly better:
function SomeClass() {
  this.BASE_URL = 'http://example.com';
  someInitialisation();

  this.method = function(urls) {
    return urls.map(function(url) {
      return this.BASE_URL + url;
    }.bind(this));
  };
}

// Now:
function SomeClass() {
  this.BASE_URL = 'http://example.com';
  someInitialisation();

  this.method = function(urls) {
    return urls.map((url) => this.BASE_URL + url);
  };
}
Classes

JS now has native classes! Rewriting the previous example:

class SomeClass {
  constructor {
    this.BASE_URL ='http://example.com';
    someInitialisation();
  }

  method(urls) {
    return urls.map((url) => this.BASE_URL + url);
  }
}

gulp

Traditional build systems are generally sequential, defined mostly following shell scripts:

# Rough translation of gulpfile.js in
# "shell-style" traditional build format.
# Of course the gulpfile does a LOT more!
cd src

cd images
pngoptim -input *.png \
  -output ../out/
  # Optimise all images
cd ..

cd tiles
mkdir -p ../intermediate
spritesheet -input *.png \
  -output ../intermediate/tiles.png \
  -less ../intermediate/tiles.less
  # Create spritesheets
cd ../intermediate
pngoptim -input tiles.png \
  -output ../out/tiles.png
  # Optimise spritesheet
cd ..

cd less
cp ../intermediate/tiles.less .
lessc scadafarm.less \
  > ../intermediate/scadafarm.css
  # Compile LESS
rm tiles.less
cd ..

cd intermediate
csswring scadafarm.css \
  > ../out/scadafarm.css
  # Minify css
cd ..

mkdir -p ../websites/assets/{images,css}
cp out/*.png ../website/assets/images/
cp out/*.css ../website/assets/css/

Gulp uses streams of files that it applies transforms on:

gulp.src('images/*.png')            // read a set of file
.pipe(pngoptim())                   // apply optimisations
.pipe(gulp.dest('intermediate/'))   // write to a directory

You wrap each set of transformations in a task:

gulp.task('images', () =>
  gulp.src('images/*.png')
  .pipe(pngoptim())
  .pipe(gulp.dest('intermediate/'))
)

And specify dependencies:

gulp.task('images', () => {})
gulp.task('tiles', () => {})
gulp.task('style', ['tiles'] () => {})
gulp.task('copy-assets', ['images', 'style'], () => {})

Gulp then resolves the dependency graph and takes care of running all tasks with maximum concurrency. In this case, images is probably going to take a long time, but in that time tiles and style will run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment