Modern Web Developement

86
Modern Web Development @ipeychev

Transcript of Modern Web Developement

Page 1: Modern Web Developement

Modern Web Development

@ipeychev

Page 2: Modern Web Developement

Evolution of the Web frameworks and libraries

Page 3: Modern Web Developement

2006 2015

Page 4: Modern Web Developement

Pros Cons

Cross browser API

Powerful DOM queries

OOTB Ajax

Plugins system

Tight coupling with HTML tags

Tracking DOM events is hard

Misleading API("on" might be on or delegate, it depends)

Slow

Page 5: Modern Web Developement

2006 2014

Page 6: Modern Web Developement

Pros Cons

Cross browser API

Powerful DOM queries

OOTB Ajax, PJax, etc.

Plugins system

Traversing DOM was slow

Some of the modules were crappy

Tried to provide everything

Contributing was hardLoading modules

WidgetsApp framework

Designed to serve the old browsers

Page 7: Modern Web Developement

2009 2015

Page 8: Modern Web Developement

Pros Cons

Two way data binding

Declarative HTML

Complex conceptsSlow dirty checkingLogic everywhere

Client-side framework(rendering on the server is possible, but tricky)

They invented Karma :)

Page 9: Modern Web Developement

2010 2015

Page 10: Modern Web Developement

Pros Cons

Auto-synced models via REST API

Robust event system

Bare-bones featuresjQuery like views

Page 11: Modern Web Developement

2011 2015

Page 12: Modern Web Developement

Pros Cons

True MVC pattern

Templating system based on Handlebars

A lot of black magicContext switchingComplicated two-way data binding

Page 13: Modern Web Developement

2013 2015

REACT

Page 14: Modern Web Developement

Pros Cons

Minimal (view part only)

One-way data flow

Requires change of mindset

Simple concepts

Fast (60 fps)

Isomorphic applications, client-side applications, native applications

Abolishes the rules made of stone

REACT

Page 15: Modern Web Developement

React in a nutshell

Page 16: Modern Web Developement

React in a nutshell

Library, not a framework

Implements one-way reactive data

flow

Blazingly fast

Page 17: Modern Web Developement

React in a nutshell

Virtual DOM

JSX

JavaScript syntax extension (JSX)

Page 18: Modern Web Developement

React in a nutshell

Native applications

Isomorphic applications

Client-side applications

Page 19: Modern Web Developement

Creating UI with React

Page 20: Modern Web Developement

Main UI

Nested Components

Data flow

Page 21: Modern Web Developement

Creating a component

Render the component

Change the state

Page 22: Modern Web Developement

And rendering is fast

Virtual DOM rulez

Performance

Page 23: Modern Web Developement

EcmaScript 6 and 7

Page 24: Modern Web Developement

ES6 & 7 main features

Classes

Modules importing

Syntactic sugar over functions

Class and properties decorators (annotations)

Variables and constants

Block scoping

Page 25: Modern Web Developement

Built-in Promises

Template strings

Default function parameter values

Function generators

Symbols

Proxies … more here

ES6 & 7 main features

Page 26: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Page 27: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Imports

Page 28: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Classannotations

Page 29: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Classes

Page 30: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Inheritance

Page 31: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Functions

Page 32: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Fat arrows

Page 33: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Props annotations

Page 34: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Classproperties

Page 35: Modern Web Developement

EcmaScript 6 and 7 in action

1 import screwdriver from '/tools/bag'; 2 import pliers from '/tools/bag'; 3 import Visible from '/state/Visible'; 4 import {Attribute as attr} from '/attributes/Attribute'; 5 6 @Visible 7 class Component extends Base { 8 constructor() { 9 super(); 10 } 11 12 helloWorld() { 13 return { 14 myProp: () => { return 'Hello World!';} 15 }; 16 } 17 18 @attr 19 prop1 = 23; 20 } 21 22 export default Some;

Module exports

Page 36: Modern Web Developement

What is the situation

now?

Page 37: Modern Web Developement

One-way directional data flow wins

Page 38: Modern Web Developement

Plenty of React-wanna-be frameworks and libraries

Plenty of Flux implementations

Page 39: Modern Web Developement

React like libraries/frameworks

Mithril

Mercury

Vue.js

Ripple.js

Riot Reactive

Cito.js

Hyperd

Page 40: Modern Web Developement

React like libraries/frameworks

Cyclejs

r-js

Copernicium

jFlux

vbridge

Tungsten.js

Cape.js

… more here

Page 41: Modern Web Developement

Plenty of Virtual DOM implementations

A lot of on GitHub

as part of framework/library or just like a module

Page 42: Modern Web Developement

The other frameworks evolve

Ember changes to benefit from React’s ideas

Angular too

Page 43: Modern Web Developement

Framework evolution in the wrong way

Page 44: Modern Web Developement

Reactive programming

(warning - changes the mindset)

Page 45: Modern Web Developement

Changes the way we think about

asynchronous programming

Page 46: Modern Web Developement

Everything is Observable

Reactive programming

including the events

Page 47: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Page 48: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Get the drag target

Page 49: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Observables from events

Page 50: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Process these as arrays

Page 51: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Map mouse move

Page 52: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Stop on mouse up

Page 53: Modern Web Developement

Let’s implement Drag&Drop

1 var dragTarget = document.getElementById('dragTarget'); 2 3 var mousedown = Observable.fromEvent(dragTarget, 'mousedown'); 4 var mousemove = Observable.fromEvent(document, 'mousemove'); 5 var mouseup = Observable.fromEvent(dragTarget, 'mouseup'); 6 7 var mousedrag = mousedown.flatMap(function(mousedown) { 8 var startX = mousedown.offsetX, 9 startY = mousedown.offsetY; 10 11 return mousemove.map(function(mousemove) { 12 mousemove.preventDefault(); 13 14 return { 15 left: mousemove.clientX - startX, 16 top: mousemove.clientY - startY 17 }; 18 }).takeUntil(mouseup); 19 }); 20 21 var subscription = mousedrag.subscribe(function(pos) { 22 dragTarget.style.top = pos.top + 'px'; 23 dragTarget.style.left = pos.left + 'px'; 24 });

Update position on mousedrag

Page 54: Modern Web Developement
Page 55: Modern Web Developement

CSSacronym for CSS Seriously Sucks ;)

Page 56: Modern Web Developement

Flexbox

Page 57: Modern Web Developement

Can be dynamically collapsed or uncollapsed along the main axis while preserving the container’s cross size.

Can be laid out in any flow direction (leftwards, rightwards, downwards, upwards)

Can have display order reversed or rearranged at the style layer (i.e., visual order can be independent of source and speech order)

Can be laid out linearly along a single (main) axis or wrapped into multiple lines along a secondary (cross) axis

Can “flex” element’s sizes to respond to the available space

Can be aligned with respect to their container or each other

Child elements in Flexbox

Page 58: Modern Web Developement

Modular CSS

Page 59: Modern Web Developement

Every time you add CSS rule,

Global CSS sucks

you risk clashing with something else

Page 60: Modern Web Developement

Webpack’s CSS modules

Page 61: Modern Web Developement

CSS as modules,local scope by default

Page 62: Modern Web Developement

Webpack’s CSS Modules

The CSS for a module is isolated,

despite of class names like ‘.main’

Page 63: Modern Web Developement

Webpack’s CSS Modules

You can extend

and import classes

Page 64: Modern Web Developement

Webpack’s CSS Modules

MyComponent.css

1 .main { 2 border-width: 2px; 3 border-style: solid; 4 border-color: #777; 5 padding: 0 20px; 6 margin: 0 6px; 7 max-width: 400px; 8 } 9 10 .text { 11 color: #777; 12 font-size: 24px; 13 font-family: helvetica, arial, sans-serif; 14 font-weight: 600; 15 }

Page 65: Modern Web Developement

Webpack’s CSS Modules

MyComponent.js

1 import styles from './MyComponent.css'; 2 import React, {Component} from 'react'; 3 4 export default class MyComponent extends Component { 5 6 render() { 7 return ( 8 <div className={styles.main}> 9 <p className={styles.text}>Scoped Selectors</p> 10 </div> 11 ); 12 } 13 };

Page 66: Modern Web Developement

Webpack’s CSS Modules

Webpack will compile the CSS classes

prefix and isolate them so they won’t clash

Page 67: Modern Web Developement

Webpack’s CSS Modules

Global selectors are available

(but please avoid them)

Page 68: Modern Web Developement

1 .main { 2 border-width: 2px; 3 border-style: solid; 4 border-color: #777; 5 padding: 0 20px; 6 margin: 0 6px; 7 max-width: 400px; 8 } 9 10 .main :global p { 11 color: #777; 12 font-size: 24px; 13 font-family: helvetica, arial, sans-serif; 14 font-weight: 600; 15 }

Webpack’s CSS Modules

MyComponent.css

This will style al `p` inside the component

Page 69: Modern Web Developement

Webpack’s CSS Modules

MyComponent.js

1 import styles from './MyComponent.css'; 2 import React, {Component} from 'react'; 3 4 export default class MyComponent extends Component { 5 6 render() { 7 return ( 8 <div className={styles.main}> 9 <p>content</p> 10 </div> 11 ); 12 } 13 }; `p` will be styled b/c of

the global selector

Page 70: Modern Web Developement

Webpack’s CSS Modules

CSS inheritance from shared modules

Page 71: Modern Web Developement

Webpack’s CSS Modules

1 .container { 2 border-width: 2px; 3 border-style: solid; 4 padding: 0 20px; 5 margin: 0 6px; 6 max-width: 400px; 7 }

layout.css

Page 72: Modern Web Developement

Webpack’s CSS Modules

1 .main { 2 extends: container from "layout.css"; 3 border-color: red; 4 }

MyComponent.css

Page 73: Modern Web Developement

This is CSS finally fixed

Page 74: Modern Web Developement

Testing

Page 75: Modern Web Developement
Page 76: Modern Web Developement

Unit tests

Karma + Mocha + Chai + Sinon

Page 77: Modern Web Developement

Integration/Functional tests

Pioneer.js

Nightwatch.js

Intern … more here

Page 78: Modern Web Developement

Pioneer.js

You write the tests in the English-like Gherkin syntax

Cucumber

Page 79: Modern Web Developement

Pioneer.js

Feature: TODO MVC

Background:

Given I am viewing todomvc

Scenario: Adding and Completing

When I add a new todo

And I finish it

Then I should see no undone todos

Page 80: Modern Web Developement

Pioneer.js

1 module.exports = function() { 2 this.Given(/^I am viewing todomvc$/, function() { 3 return this.driver.visit('http://todomvc.com/architecture-examples/backbone/'); 4 }); 5 6 this.When(/^I add a new todo$/, function() { 7 return this.Widget.fill({ 8 selector: '#new-todo', 9 value: ['doge', Driver.Key.Enter] 10 }) 11 });

Page 81: Modern Web Developement

Pioneer.js

1 this.When(/^I finish it$/, function() { 2 return this.Widget.click({ 3 selector: '#todo-list .toggle' 4 }); 5 }); 6 return this.Then(/^I should see no undone todos$/, function() { 7 return this.Widget.read({ 8 selector: '#todo-count' 9 }).should.eventually.eql('0 items left'); 10 }); 11 };

Page 82: Modern Web Developement

Future

Page 83: Modern Web Developement

?

Page 84: Modern Web Developement

!

Page 85: Modern Web Developement

It is yours, work on it

Page 86: Modern Web Developement

Thank you!

ipeychev