Aligning Ember with
 Web Standards EmberConf 2015
@mixonic Matthew Beale 201 Created
The JavaScript standardization
 process is about to change #1
STANDARDS PROCESS
WHATWG + W3C TC39 + Ecma International
WHATWG + W3C TC39 + Ecma International DOM HTML WebComponents XHR, Fetch Promises for loops var, let, const classes
WHATWG W3C TC39 Ecma International
WHATWG W3C TC39 Ecma International WORKING GROUPS STANDARDS GROUPS
The plan at the time was to finish the specification this year and publish a snapshot of "HTML5" in 2012. However, shortly after that we realized that the demand for new features in HTML remained high, and so we would have to continue maintaining HTML and adding features to it before we could call “HTML5" complete, and as a result we moved to a new development model, where the technology is not versioned and instead we just have a living document that defines the technology as it evolves. Ian Hickson, 2011
“Living Standard”
ES3
ES4
ES5
ES6
ES6
ES2015
“ES2015” signifies a new
 standardization process
github.com/
 tc39/ecma262
0. Strawman 1. Proposal 2. Draft 3. Candidate 4. Finished
0. Strawman 1. Proposal -> Polyfills 2. Draft -> Experimental 3. Candidate -> Compliant 4. Finished -> Shipping
a “Living Web”
Aligning with standards
 is not a one time event
Aligning with standards
 is not free
Why standards?
Productivity
1. are portable 2. reflect best practices 3. endure Standards…
Participants win
Design Polyfill, demo Real world use Learning
Design Polyfill, demo Real world use Learning
2. Transpilers are here to stay
This is not the first time features have been added to JavaScript
ES3 -> ES5
HTML5
“Polyfill” - Remy Sharp
ES5 -> ES2015
var map = new Map(); map.set('key', 'value'); var value = map.get('key');
var map = new Map(); map.set('key', 'value'); var value = map.get('key');
1 var delayed = new Promise( 2 function(resolve, reject){ 3 setTimeout(resolve, 100); 4 } 5 ); 6 delayed.then(function(){ 7 console.log('HTMLBars'); 8 });
1 var delayed = new Promise( 2 function(resolve, reject){ 3 setTimeout(resolve, 100); 4 } 5 ); 6 delayed.then(function(){ 7 console.log('HTMLBars'); 8 });
1 var loggingObject = new Proxy({}, { 2 get(target, propertyKey, receiver) { 3 console.log('GET '+propertyKey); 4 return target[propertyKey]; 5 } 6 }); 7 8 loggingObject.whatever; // Logs: GET whatever
1 var loggingObject = new Proxy({}, { 2 get(target, propertyKey, receiver) { 3 console.log('GET '+propertyKey); 4 return target[propertyKey]; 5 } 6 }); 7 8 loggingObject.whatever; // Logs: GET whatever
1 var runner = { 2 count: 0, 3 call: function() { 4 setTimeout(() => { 5 console.log(this.count++); 6 }, 100); 7 } 8 }; 9 10 runner.call();
1 var runner = { 2 count: 0, 3 call: function() { 4 setTimeout(() => { 5 console.log(this.count++); 6 }, 100); 7 } 8 }; 9 10 runner.call();
“Babel will turn your ES6+ code into ES5 friendly code, so you can start using it right now without waiting for browser support.”
1 "use strict"; 2 3 var runner = { 4 count: 0, 5 call: function call() { 6 var _this = this; 7 8 setTimeout(function () { 9 console.log(_this.count++); 10 }, 100); 11 } 12 }; 13 14 runner.call(); 1 var runner = { 2 count: 0, 3 call: function() { 4 setTimeout(() => { 5 console.log(this.count++); 6 }, 100); 7 } 8 }; 9 10 runner.call();
1. syntax (fat arrow, let) 2. APIs (Map, Set) 3. not everything Enables new…
“Not born to die” - James Kyle
kangax.github.io/compat-table/es6
ES2015 feature: Uint8Array
ES2015 feature: Uint8Array IE10+
ES2015 feature: Spread Operator var list = [1,2,3]; Math.max(...list);
ES2015 feature: Spread Operator var list = [1,2,3]; Math.max(...list); Firefox only
ES2015 feature: Block-level function scope 1 "use strict"; 2 function a(){ return 1; } 3 { 4 function a(){ return 2; } 5 }; 6 7 a() === 1;
ES2015 feature: Block-level function scope Chrome only 1 "use strict"; 2 function a(){ return 1; } 3 { 4 function a(){ return 2; } 5 }; 6 7 a() === 1;
The target platforms of Babel
 are inconsistent
Babel Chrome Firefox
The platforms your application supports will drive what features are transpiled.
Targeting platforms can be done by tweaking the enabled features list.
IMO a mapping to platforms would be better.
What you transpile today,
 you will blacklist in two years
Yes, you will be transpiling
 in two years
Yes, you will be transpiling
 in five years
Yes, you will be transpiling
 in ?!!?!?! years
Transpilers are here to stay
3. Aligning Ember’s object model
1. stable 2. a good pattern 3. implemented correctly 4. implemented performantly Is this feature:
ES Classes
1. class 2. extend 3. super Three new tools:
1 class Car { 2 constructor(gearCount){ 3 this.gearCount = gearCount; 4 } 5 6 toString() { 7 return `A car with: ${gearCount} gears`; 8 } 9 } 10 11 var car = new Car(3); 12 car.toString(); // A car with 3 gears
1 class Vehicle { 2 constructor(gearCount){ 3 this.gearCount = gearCount; 4 } 5 } 6 class Car extends Vehicle { 7 toString() { 8 return `A car with: ${this.gearCount} gears`; 9 } 10 } 11 12 var car = new Car(3); 13 car.toString(); // A car with 3 gears
1 class Vehicle { 2 constructor(gearCount){ 3 this.gearCount = gearCount; 4 } 5 toString() { 6 return `${this.gearCount} gears`; 7 } 8 } 9 class Car extends Vehicle { 10 toString() { 11 return `A car with: ${super.toString()}`; 12 } 13 }
1 class Vehicle { 2 constructor(gearCount){ 3 this.gearCount = gearCount; 4 } 5 toString() { 6 return `${this.gearCount} gears`; 7 } 8 } 9 class Car extends Vehicle { 10 constructor(...args) { 11 console.log(`Created with ${args[0]}`); 12 super(args); 13 } 14 toString() { 15 return `A car with: ${super.toString()}`; 16 } 17 }
1. new syntax 2. super semantics change 3. mixins gotachas:
4. setUnknownProperty 5. merged/concat properties 6. transpiler ouput?! more gotachas:
7. only halfway there
7. only halfway there ES Decorators
1 class Car { 2 +attr('gearsCount') 3 +attr('wheelsCount') 4 5 constructor(gearsCount) { 6 this.gearsCount = gearsCount; 7 } 8 9 -dependsOn('gearsCount') 10 get isModern() { 11 return this.gearsCount > 3; 12 } 13 } 14 15 var car = new Car(3); 16 car.isModern; // false
Aligning
1. provide legacy wrapper 2. use syntax as a carrot 3. private use can start sooner strategy:
1 import EmberObject from "ember/object"; 2 import computed from "ember/computed"; 3 4 class Car extends EmberObject.extend({ 5 6 init(gearsCount) { 7 this._super(...arguments); 8 this.set('gearsCount', gearsCount); 9 }, 10 11 isModern: computed('gearsCount', function(){ 12 return this.get('gearsCount') > 3; 13 }) 14 }); 15 16 export default Car;
1 import EmberObject from "ember/object"; 2 3 class Car extends EmberObject { 4 5 constructor(gearsCount) { 6 super(...arguments); 7 this.gearsCount = gearsCount; 8 } 9 10 get isModern() { 11 return this.gearsCount > 3; 12 } 13 } 14 15 export default Car;
1 import Component from "ember/component"; 2 3 class Car extends Component { 4 5 get isModern() { 6 return this.attrs.gearsCount > 3; 7 } 8 } 9 10 export default Car;
This is a story of Ember 2.0 -> 3.0
Reminder: Standards are a two-way street
ONE MORE THING
201-created.com/
 ember-community-survey-2015 @ClimbingNarc
201-created.com/ember-community-survey-2015
201-created.com/ember-community-survey-2015
Thank you, you wonderful people. @mixonic

Aligning Ember.js with Web Standards