WEB COMPONENTS
FUTURE OF WEB DEV
/Matjaž Lipuš @MatjazL
AGENDA
SPA
Current state
Future technologies
Lets build an app
PRE SPA
jQuery
element.click(handler)
$.ajax()
element.html(result)
SPA
router
templates
app state
data
MVC
SPA TOOLING
haml, jade
less, scss
ES6 (Babel)
TypeScript
npm, bower, jspm
grunt, gulp
SPA FRAMEWORKS
router (state, url)
components
templating
helpers (http, url)
dependency injection
simple testing
SPA FRAMEWORKS
Backbone.js
Knockout
EmberJS
React + Flux
AngularJS
BACKBONE.JS
templates
models/collections
routing
KNOCKOUT
two way binding
custom events
EMBERJS
structured code
convention over configuration
REACT + FLUX
virtual DOM (diff, fast updates)
JSX
evented approach (dispatcher)
ANGULAR 1
MVVM
Dependency Injection
Unit testing (karma)
Integration testing (protractor)
5 years ago
ES6 - ES 2015
official standard since last week ;)
class syntax, arrow functions, maps, sets, promises,
generators
Still JavaScript (prototypal inheritance)
ES6 PROMISE
new Promise(function(resolve, reject) {
async(function(error, response) {
if (error) {
reject(error);
} else {
resolve(response);
}
})
});
Promise.all([])
Promise.resolve()
Promise.reject()
FETCH()
bower install fetch
fetch('/users')
.then(function(response) {
return response.json();
}).then(function(json) {
console.log('parsed json', json);
}).catch(function(ex) {
console.error('parsing failed', ex);
})
fetch('/users', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Bart',
login: 'user'
})
})
ES7 DECORATORS
@inject(Users)
class List {
constructor(Users) {
this.Users = Users;
}
fetchUser(id) {
return this.Users.fetch(id);
}
}
class Person {
firstName = 'John';
lastName = 'Doe';
@computedFrom('firstName', 'lastName')
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
WEB COMPONENTS
<hello-there name="everybody"></hello-there>
Abstraction and encapsulation
Templates
HTML imports
Shadow DOM
Custom elements
WEB COMPONENTS TODAY
Chrome's "built-in" components
dd/mm/yyyy --:--
1:10
Can I use?
<HELLO-THERE>
<hello-there name="everybody"></hello-there>
<template id="hello-there-tpl">
<style>
p { color: orange; }
</style>
<p>Hello <span></span>!</p>
</template>
Hello everybody!
<HELLO-THERE> 2/2
var HelloThere = document.registerElement('hello-there', {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
this.name = this.getAttribute('name') || 'world';
var tmpl = document.querySelector('#hello-there-tpl');
var clone = document.importNode(tmpl.content, true);
clone.querySelector('span').textContent = this.name;
this.createShadowRoot().appendChild(clone);
}
},
alert: {
value: function() {
alert(this.name);
}
}
})
PRESENT
polyfills
simplified API for web components
Polymer project
X-Tag
Components kitchen
FUTURE
Angular 2, Aurelia, Ember 2
built on web components concepts
router, components, templates, DI, component's lifecycle
Aurelia Angular 2
Object.observe() zone.js
two way binding immutable data O(1)
convention over
configuration
decorators
attr.bind, click.trigger templates using *, () & []
MOBILE
web view
Appcelerator, cordova + ionic (2)
(iOS)
(all platforms)
React native
NativeScript
LETS BUILD AN APP
Aurelia
Router
Flickr
Child router
Library mini app
Polymer components
LETS START!
git clone -b step-1 
https://github.com/matjaz/webcomponents-workshop.git
cd webcomponents-workshop
cd aurelia
npm install
npm install -g gulp jspm
jspm install -y
gulp watch
ADDING ROUTER...
git checkout step-2
configureRouter
.map()
navigation
@bindable, @computedFrom
tests
ADDING FLICKR
git checkout step-3
Dependency injection
Screen activation cycle
Test stub
ADDING CHILD ROUTER
git checkout step-4
ADDING CHILD ROUTER
git checkout step-4
ADDING LIBRARY
git checkout step-5
cd server
npm i
npm start
REST
Custom elements
repeat, binding
ADDING POLYMER COMPONENTS
bower install google-map
bower install pazguille/github-card
git checkout step-6
Frameworks co-existance
Code re-use
QUESTIONS?
THANK YOU!
github.com/matjaz/webcomponents-workshop
/Matjaž Lipuš @MatjazL

Web components