What is it like to learn front-end in 2018?

What was it like to learn front-end in 1991

First Website ever

Text

What was it like to learn front-end in 1995

What was it like to learn front-end in 1996

What was it like to learn front-end in 1998

var xmlHttp;
// use the ActiveX control for IE5.x and IE6
try {
    xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
} catch (othermicrosoft){
    try { 
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } 
    catch (native) {
        // If IE7, Mozilla, Safari, etc: Use native object
        xmlHttp = new XMLHttpRequest();
    } 
} 

2006

Usage of JavaScript libraries for websites in 2018

jQuery usage trend 2017-2018

2010

2014

2018

HTML

What is HTML?

W3C HTML

WHATWG  HTML

HTML 5.1

<picture>
<picture>
        <source media="(min-width: 650px)" srcset="images/kitten-large.png">
        <source media="(min-width: 465px)" srcset="images/kitten-medium.png">
        <img src="images/kitten-small.png" alt="a cute kitten">
</picture>

zero-width images

<img src="https://stats.com/c?sample.com" width="0" height="0" alt="">
<details>/<summary>
<h2>Error Message</h2>
<details>
    <summary>We couldn't finish downloading this video.</summary>
    <dl>
        <dt>File name:</dt><dd>yourfile.mp4</dd>
        <dt>File size:</dt><dd>100 MB</dd>
        <dt>Duration:</dt><dd>00:05:27</dd>
    </dl>
</details>
<menu>/<menuitem>
<button contextmenu="rightclickmenu">Right click me</button>
<menu type="context" id="rightclickmenu">
    <menuitem type="checkbox" label="I ♥ HTML5.1.">
</menu>

Inline scripts are evil

Good practice: disable inline JS with CSP

Content-Security-Policy: script-src https://example.com/
nonce attribute
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  //Some inline code I cant remove yet, but need to asap.
</script>

If you absolutely must use it ...

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

rel="noopener"

<a href="#" target="_blank" rel="noopener">
  Your link that won't make troubles
</a>
  • When your page links to another page using target="_blank", the new page runs on the same process as your page. 
  • target="_blank" is a security vulnerability.
    The new page has access to your window object via window.opener, and it can navigate your page to a different URL using window.opener.location = newURL.

HTML 5.2

<menu>/<menuitem>
<button contextmenu="rightclickmenu">Right click me</button>
<menu type="context" id="rightclickmenu">
    <menuitem type="checkbox" label="I ♥ HTML5.1.">
</menu>
<dialog>
<button id="btnGreet">Greet</button>
<dialog id="greetDialog">
    <p>Greetings!</p>
    <button id="btnClose">Close</button>
</dialog>
btnGreet.addEventListener('click', () => greetDialog.showModal() );
btnClose.addEventListener('click', () => greetDialog.close() );
multiple <main> elements
<main>...</main>
<main hidden>...</main>
<main hidden>...</main>
  • With HTML 5.2, we can now have multiple <main> elements in our markup, as long as only one is visible to the user at any given time.
  • Any extra elements must be hidden using the hidden attribute.
 <iframe allowpaymentrequest>
<iframe allowpaymentrequest>


</iframe>
<style> in <body>
<body>
    <p>I’m cornflowerblue!</p>
    <style>
        p { color: cornflowerblue; }
    </style>
    <p>I’m cornflowerblue!</p>
</body>

A style element should preferably be used in the head of the document. The use of style in the body of the document may cause restyling, trigger layout and/or cause repainting, and hence, should be used with care.

<meta name="theme-color">
<meta name="theme-color" content="red">
<script type="module>
<script type="module" src="./app/app.js"></script>
import utils from "./utils.js";

index.html:

app.js:

Note: module specifier must start with either ./, ../ or /

Newly Invalid practices

No inline, floated, or blocked children of <p>

 

  • No inline blocks
  • No inline tables
  • No floated and positioned positioned blocks

No Strict Doctypes

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

CSS

CSS Grid

CSS Grid

Developer Tools

CSS Variables (Custom Properties)

:root {
  --some-property-name: someValue;
}

selector {
  property: var(--some-property-name);
}

Variables: SCSS vs CSS

$color-1: tomato;
$color-2: olive;
$color-3: gold;

:root {
    --body-color: $color-1;
    @media (max-width: 960px){ --body-color: $color-3; }
    @media (max-width: 480px){ --body-color: $color-2; }
}

body { background-color: var(--body-color); }

CSS Modules

How CSS Modules work

CSS Evolution

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

JavaScript

JavaScript is likely not what you think it is

Which programming languages are most similar to JavaScript?

Scheme to JavaScript

  1. ES1

  2. ES2

  3. ES3

  4. ES5

  5. ES5.1

Complete list of EcmaScript Editions

  1. ES2015

  2. ES2016

  3. ES2017

  4. ES2018

ES2015

Swap values

var a = 1, b = 2;

// Junior
var tmp = b;
b = a;
a = tmp;

// Intermediate
a ^= b;
b ^= a;
a ^= b;

// Senior
a = [b, b=a][0];

// Architect
b = (function(a){return a})(a, a=b);

ES5

Swap values

ES2015

let a = 1, b = 2;

[a, b] = [b, a]

Generate array

function seq(n) {
  var result = [];
  for (var i = 0; i < n; i++) {
      result.push(i);
  }
  return result;
}

ES5

[0, 1, 2, 3, ..., N-1]

Generate array

ES2015

const seq = n => [...Array(n).keys()];
[0, 1, 2, 3, ..., N-1]

ES2016

[1, 2, 3].includes(1) // true

a ** b // Math.pow(a, b)

ES2017

ES2018

Major new features:

New regular expression features:

Other new features:

Writing JS
modern way

Async code

callbacks

const addOneTo = function(number, callback) {
    const result = number + 1;
    if (callback) {
        callback(result);
    }
}
// 5 + 1 = 6
addOneTo(5, function(res){
    console.log(res);
})
// 5 + 1 + 1 + 1 + 1 + 1 = 10
addOneTo(5, function(res1) {
    addOneTo(res1, function(res2) {
        addOneTo(res2, function(res3) {
            addOneTo(res3, function(res4) {
                addOneTo(res4, function(res5) {
                    console.log(res5);
                });
            });
        });
    });
});

ES2015: promises

const addOneTo = function(number) {
    const result = number + 1;
    return new Promise(function(resolve, reject) {
        resolve(result);
    });
}
// 5 + 1 = 6
addOneTo(5)
    .then( res => console.log(res) );
// 5 + 1 + 1 + 1 + 1 + 1 = 10
addOneTo(5)
    .then(addOneTo)
    .then(addOneTo)
    .then(addOneTo)
    .then(addOneTo)
    .then(console.log)

ES2017: async/await

const addOnTo = function(number){
    const result = number + 1;
    return new Promise(function(resolve, reject) {
        resolve(result);
    });
}
async function calc(){
    const res1 = await addOnTo(5);
    const res2 = await addOnTo(res1);
    const res3 = await addOnTo(res2);
    const res4 = await addOnTo(res3);
    const res5 = await addOnTo(res4);
    console.log(res5);
}
calc();

Observables

<input id="inpt" type="text" >
<h3>You entered:</h3>
<div id="results"></div>
Rx.Observable
  .fromEvent(inpt, 'keyup')
  .map(x => x.currentTarget.value)
  .debounceTime(500) 
  .subscribe(x => result.innerHTML += `<br>${x}`);

RxJS Sample

Functional

Approach

What's wrong with this code?

function seq(n) {
  var result = [];
  for (var i = 0; i < n; i++) {
      result.push(i);
  }
  return result;
}

Simple steps to adopt functional approach in JS

  1. Build pure functions 
  2. Use constants where possible 
  3. Avoid loops
  • Consider the numbers 6969 and 9116. When you rotate them 180 degrees (upside down), these numbers remain the same.
  • To clarify, if we write them down on a paper and turn the paper upside down, the numbers will be the same. Try it and see! Some numbers such as 2 or 5 don't yield numbers when rotated.
  • Given a range, return the count of upside down numbers within that range. For example, solve(0,10) = 3, because there are only 3 upside down numbers >= 0 and < 10. They are 0, 1, 8.

Sample task: upside down

function solve(x, y) {
  let total = 0;
  for (let i = x; i < y; i++) {
    let current = i.toString();
    let final = '';
    let split = current.split('').reverse();
    for (let j = 0; j < split.length; j++) {
      let x = split[j];
      if (x === '0' || x === '1' || x === '8') {
        final += x;
      } else if (x === '6') {
        final += '9';
      } else if (x === '9') {
        final += '6';
      } else {
        break;
      }
    }
    if (final === current) {
      total++;
    }
  }
  return total;
};

Sample: non-functional

function solve(x, y) {
 return [...'_'.repeat(y - x + 1)]
    .map( (_,i) => x + i )
    .reduce( (acc, n) => n == rotate(n) ? ++acc : acc, 0 );
};

function rotate(num) {
  const digitsRotated = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'};
  return String(num)
    .split('')
    .reverse()
    .map(d => digitsRotated[d])
    .join('');
}

Sample: functional

Going Deeper...

const sumBelow = (number, sum = 0) => (
  number === 0 
    ? sum
    : sumBelow(number - 1, sum + number)
)

Consider the code

console.log(sumBelow(1000));
console.log(sumBelow(10000));

Sometimes in future...

const trampoline = fn => (...args) => {
  let result = fn(...args)
  
  while (typeof result === 'function') {
    result = result()
  }
  
  return result
}

const sumBelowRec = (number, sum = 0) => (
  number === 0
    ? sum
    : () => sumBelowRec(number - 1, sum + number)
)

Trampoline

const sumBelow = trampoline(sumBelowRec);
console.log(sumBelow(10000));
console.log(sumBelow(100000));
console.log(sumBelow(1000000));

Frameworks

Rubber duck debugging

Redux

Technologies

Isomorphic/Universal
JavaScript

Universal JS Architecture

Serverless

Serverless Architecture

Learning the smart way

Know your path

Take courses

Visit events

Practice on CodeWars

Learn with mentor

Become an Engineer

Thank you!

Links

Made with Slides.com