What is it like to learn front-end in 2018?
Vyacheslav Koldovskyy programmingmentor.com t.me/programmingmentor
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
- Version-based
- www.w3.org/TR/html52
WHATWG HTML
- No versions, just living standard
- html.spec.whatwg.org/multipage
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
-
ES1
-
ES2
-
ES3
-
ES5
-
ES5.1
Complete list of EcmaScript Editions
-
ES2015
-
ES2016
-
ES2017
-
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:
- Asynchronous Iteration (Domenic Denicola, Kevin Smith)
- Rest/Spread Properties (Sebastian Markbåge)
New regular expression features:
- RegExp named capture groups (Gorkem Yakin, Daniel Ehrenberg)
- RegExp Unicode Property Escapes (Mathias Bynens)
- RegExp Lookbehind Assertions (Gorkem Yakin, Nozomu Katō, Daniel Ehrenberg)
- s (dotAll) flag for regular expressions (Mathias Bynens)
Other new features:
- Promise.prototype.finally() (Jordan Harband)
- Template Literal Revision (Tim Disney)
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
- Build pure functions
- Use constants where possible
- 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!
Vyacheslav Koldovskyy programmingmentor.com t.me/programmingmentor
Links
- Ilya Grigorik High Performance Browser Networking
- https://www.hongkiat.com/blog/html-5-1-new-features/
- https://developers.google.com/web/fundamentals/security/csp/
- https://glebbahmutov.com/blog/disable-inline-javascript-for-security/
- https://blog.whatwg.org/js-modules
- https://www.smashingmagazine.com/2017/06/building-production-ready-css-grid-layout/
- https://gridbyexample.com/
- https://www.xanthir.com/blog/b4KT0
- https://developers.google.com/web/updates/2016/02/css-variables-why-should-you-care
- https://m.alphasights.com/css-evolution-from-css-sass-bem-css-modules-to-styled-components-d4c1da3a659b
- https://www.smashingmagazine.com/2016/12/progressive-web-amps/
- https://medium.com/@frontman/how-swap-two-values-without-temporary-variables-using-javascript-8bb28f96b5f6
- http://2ality.com/2017/02/ecmascript-2018.html
- https://medium.com/@mjackson/universal-javascript-4761051b7ae9
- https://github.com/JustServerless/awesome-serverless
- http://blog.spotinst.com/2017/06/07/state-serverless-ecosystem/
- https://blog.logrocket.com/using-trampolines-to-manage-large-recursive-loops-in-javascript-d8c9db095ae3
learn-front-end-2018
By Programming Mentor (Vyacheslav Koldovskyy)
learn-front-end-2018
- 555