JSPM, ES6 &

REAL-life uses

hello!

@benjaminreid

NOUVELLER.COM/404

benjaminreid.me
github.com/nouveller

I make things on the internet

JSPM

ES6

REAL-Life uses

WHAT is JSPM?

It's a package manager!

http://jspm.io/

"Installing a widget or library should be a one line operation and a single require" — Guy bedford

https://youtu.be/szJjsduHBQQ

It does a little more

than a package manager

  • Package manager for SystemJS (Universal dynamic module loader)
  • Leverages NPM and Github
  • Loads any module format (ES6, AMD and CommonJS)
  • Transpiles your ES6 => ES5
  • Builds a single "production ready" file for you 

SHOULD i

CONSIDER JSPM or something alike?

INSTAlL JSPM

npm install jspm -g

Create a new project

mkdir my-project && cd my-project
npm install jspm --save-dev

setup jspm

jspm init

Install a package

jspm install jquery

index.html

<!doctype html>
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
  System.import('app.js');
</script>

app.js

import $ from 'jquery';

export default (function() {
  console.log('Hello world!', $);
})();

And you're done

BONUS!

jspm bundle app --inject
jspm bundle-sfx main

So what's the other side look like?

ROLLING YOUR
OWN With gulp

GULP dependcies

var gulp = require('gulp');
var babelify = require('babelify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var streamqueue = require('streamqueue');
var filter = require('gulp-filter');
var bower = require('main-bower-files');
var concat = require('gulp-concat');
var streamify = require('gulp-streamify');

dependencies via bower

function dependencies() {
  var files = bower();
  return gulp.src(files)
    .pipe(filter(['*.js']));
}

TRANSPILE YOUR ES6

function es6() {
  return browserify({ entries: 'app.js' })
    .transform(babelify)
    .bundle()
    .pipe(source('app-es6.js'));
}

the gulp task

gulp.task('scripts', function() {
  var opts = { objectMode: true };
  return streamqueue(opts, dependencies(), scripts())
    .pipe(streamify(concat('app-es6.js')))
    .pipe(gulp.dest('./dist'));
});

All together

(function() {
  function es6() {
    return browserify({ entries: 'app.js' })
      .transform(babelify)
      .bundle()
      .pipe(source('app-es6.js'));
  }

  function dependencies() {
    var files = bower();
    return gulp.src(files)
      .pipe(filter(['*.js']));
  }

  gulp.task('scripts', function() {
    var opts = { objectMode: true };
    return streamqueue(opts, dependencies(), scripts())
      .pipe(streamify(concat('app-es6.js')))
      .pipe(gulp.dest('./dist'));
  });
})();

Pro and cons

  • You have a bit of a manual setup
  • Makes structuring it how you like a little easier
  • One file with no extra requests during development
  • No "free" build script
  • Dependencies are global and not scoped to a module

So JSPM OR diy?

BONUS! (shameless plug)

var gulp = require('gulp');
var tasks = require('@benjaminreid/gulp');

gulp.task('scripts', function() {
  return tasks.es6({ src: './scripts/main.js', file: 'main.js' })
    .pipe(gulp.dest('./dist'));
});

ES6

"ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. ES6 is a significant update to the language, and the first update to the language since ES5 was standardized in 2009" — Luke Hoban

https://github.com/lukehoban/es6features

CAN I USE ES6 now?

CAVEATS

<!--[if lt IE 9]>
<script src="es5-shim.js"></script>
<script src="es5-sham.js"></script>
<![endif]-->

SHOULD I USE

ES6 now?

Modules

export default function() {
  console.log('Hello!');
};
import hello from './hello';
hello();

Modules

export var root = 'index';
export var routes = {
  'index': function() {
  },
  'profile': function() {
  }
};
import { routes, root } from './routes';
import router from './router';

router(routes, root);

Modules

export function random_range(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

export function input_enter() {
  $('input').on('keydown', function(e) {
    if (e.keyCode == 13) {
      var $next = $(this).next('input');
      if ($next.length > 0) {
        $next.focus();
      }
    }
  });
};
import * as helpers from './helpers';
helpers.input_enter();

TL;DR—modules make your life better

http://www.2ality.com/2014/09/es6-modules-final.html

classes

class App {

}

classes

import App from './app';

$(document).ready(function() {
  new App();
});

classes

class App extends BaseApp {
  constructor() {
    console.log('App was created...');
  }
  
  static version() {
    return '1.0.0';
  }
}

ARROW FUNCTIONS

class Starfield {
  constructor() {
    $(window).on('resize', () => {
      this.resize();
    });
  }

  resize() {
    // ...
  }
}

3-In-1

export default function(type = 'info') {
  // ...
  
  $panel.addClass(`content-panel--${type}`);

  function open() {
    // ...
  }

  function close() {
    // ...
  }

  return { open, close };
};

DEFAULT PARAMS

export default function(type = 'info') {
  // info == 'info'
};
function func() {
  var type = arguments.length <= 0 ||
             arguments[0] === undefined ?
             'info' : arguments[0];
}

INTERPOLATION

$panel.addClass(`content-panel--${type}`);
$panel.addClass("content-panel--" + type);

PROPerty value shorthand

var methods = { open, close };
var methods = { open: open, close: close };

ES6 in 350 bullets

https://ponyfoo.com/articles/es6

THANKS FOR LISTENING!