les slides - Blog Technique Xebia
Transcription
les slides - Blog Technique Xebia
Le JS d'aujourdhui s'écrit avec les langages de demain : { TS || ES2015 } Paul-Guillaume Déjardin @pgdejardin Un peu d'histoire : De ES3 à ES5 ● ● ● ● ● ● ● @XebiaFr mai 1995 : Javascript 1 sur Netscape 2.0 juin 1997 : ECMAScript (ES1, ECMA-262) devient le standard officiel dec 1999 : ES3 (IE 4-8) nov 2005 : Projet Tamarin (ES4, Mozilla/Adobe) => Abandonné dec 2009 : ES5 (IE9+, NodeJS), peu de changements juin 2015 : ES6/ES2015 apporte beaucoup de nouveautés juin 2016 : ES7/ES2016 en cours de ratification @pgdejardin #moisdujs Et maintenant ? ● 90% à 98% des navigateurs dit "Evergreen" (Sauf Safari : 53%) ● Node LTS v4.4.5 (50%), Node v5.11.1 (56%) et Node LTS v6.2.1 (93%) ● Comment faire ? @XebiaFr @pgdejardin #moisdujs Babel ! ● ● ● ● ● @XebiaFr Transpile ES6 (sauf Proxies), ES7 vers ES5 ou ES3 Différents "presets" (ES2015, stage-0, etc…) Différents "plugins" (ES3, ES5, ES2015, etc…) En pratique fonctionne avec IE9+, Node, evergreens, etc… Fonctionne avec… Tout ? (IDE, builders, tests, runtime, etc…) @pgdejardin #moisdujs Let et Const function f() { { let x = 'start'; { console.log(x); // okay, block scoped name, x == start const x = 'sneaky'; console.log(x); // x == sneaky // error, const x = 'foo'; } // okay, declared with `let` x = 'bar'; // x == bar // error, already declared in block let x = 'inner'; } } @XebiaFr @pgdejardin #moisdujs Const ● const ≠ immutable const author = { name: 'Bob', language: 'js' }; author.language = 'es6'; const days = ['tuesday', 'wednesday', 'thursday']; days.push('friday'); ● Utiliser immutable.js @XebiaFr @pgdejardin #moisdujs Fonctions Fléchées ● Ne redéfinit pas le this, arguments, super et new.target this.getTodos().then(todos => this.setState({ todos })); const onClickSlot = () => this.openSlot(this.slot); const mapsToProps = (state, props) => { const hash = props.location.hash; return { hash, todos: state.todos }; }; @XebiaFr @pgdejardin #moisdujs ES2015 : Les Objets et Classes ● Les littéraux avant : const edit = (item, job) => ({ type: EDIT, payload: { item: item, job: job } }); function filter(name, field) { const result = {}; result[name] = 'Title'; result[field] = field; return result; } @XebiaFr @pgdejardin #moisdujs ES2015 : Les Objets et Classes ● Les littéraux après : const edit = (item, job) => ({ type: EDIT, payload: { item, job }}); function filter(name, field) { return { [name]: 'Title', [field]: field } } @XebiaFr @pgdejardin #moisdujs ES2015 : Les Objets et Classes ● Les classes : class XSlotGrid extends HTMLElement { constructor(template) { this.innerHTML = template; } onDataChanged(slots) { ... } } @XebiaFr @pgdejardin #moisdujs ES2015 : Les Objets et Classes class TodoItem extends Component { static propTypes = { label: PropTypes.string.isRequired }; get completionTime() { return this.state; } set completionTime(value) { this.setState(value); } cleanUp() { super.cleanUp(); this.state = getInitialState(); } } @XebiaFr @pgdejardin #moisdujs Destructuration const obj = {name: 'ES2015', date: new Date('2015/06/14')}; const {name, date} = obj; // name == ES2015, date == new Date('2015/06/14') const [x, y] = ['ES2015', 'Typescript']; // x == ES2015, y == Typescript const {filters: {values}} = this.props; @XebiaFr @pgdejardin #moisdujs Default function f(x, y=12) { // y is 12 if not passed (or passed as undefined) return x + y; } f(3) == 15; @XebiaFr @pgdejardin #moisdujs For...of for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; console.log(n); } @XebiaFr @pgdejardin #moisdujs Rest function sum(...numbers) { let result = 0; for (let num of numbers) { result += num; } return result; } console.log(sum(1)); // 1 console.log(sum(1, 2, 3, 4, 5)); // 15 @XebiaFr @pgdejardin #moisdujs Spread function sum2(x, y, z) { return x + y + z; } console.log(sum2(...[1,2,3])); // 6 console.log(sum2([1, 2], 3)); // 6 @XebiaFr @pgdejardin #moisdujs Template string const msg = `This is a pretty little template string.`; const notLegalMsg = `In ES5 this is not legal.`; const name = 'Bob'; const time = 'today'; const welcomeMsg = `Hello ${name}, how are you ${time}?`; const unescaped = String.raw`In ES5 "\n" is a line-feed.`; @XebiaFr @pgdejardin #moisdujs Littéraux étendus ● Unicode ● Octal et binaire " ".length == 2; // same as ES5.1 " ".match(/./u)[0].length == 2; // new RegExp behaviour, opt-in ‘u’ "\u{20BB7}" == " " == "\uD842\uDFB7"; // new form " ".codePointAt(0) == 0x20BB7; // new String ops 0b111110111 === 503 // true 0o767 === 503 // true @XebiaFr @pgdejardin #moisdujs Les modules : Exports import _ from 'lodash'; export default function padLeft(str, num) { return _.padLeft(str, num); } export function concat(a, b) { return `${a}${b}`; } export const variable = 'a value'; export {concat as concatString, variable}; @XebiaFr @pgdejardin #moisdujs Les modules : Imports import React, { Component, PropTypes } from 'react'; import * as _ from 'lodash'; import padLeft from './StringUtil'; import {concat} from './StringUtil'; const result1 = padLeft('Hello', 2); const result2 = concat('Hello', ' World'); @XebiaFr @pgdejardin #moisdujs L'asynchronisme : Promesses SlotsService.getSlots() .then(slots => SlotsService.transformSlots(slots)) .then(newSlots => _.map(newSlots, 'name')) .catch(err => logger.error(err)); ● Garanties d'appel unique et exclusif ● Capture des exceptions / erreurs ● Composabilité @XebiaFr @pgdejardin #moisdujs L'asynchronisme : Async/Await (ES2017) async getSlotsAsync() { try { const slots = await SlotsService.getSlots(); const transformedSlots = await SlotsService.transformSlots(slots); return _.map(transformedSlots, 'name'); } catch (err) { logger.error(err) } } @XebiaFr @pgdejardin #moisdujs L'asynchronisme : Async/Await ● ● ● ● @XebiaFr Ne remplace pas les Promesses Mais plus s'ajoute en complément pour plus de clarté Code asynchrone non bloquant mais écrit comme du synchrone Le futur !!! (ES2017 Stage-3) @pgdejardin #moisdujs Typescript ! ● ● ● ● ● @XebiaFr Fait par Microsoft en 2012 Développé par Anders Heljsberg (Delphi, Turbo Pascal, C#) Open source sous License Apache 2 sur-ensemble d'ES2015/2016 se transpile en javascript @pgdejardin #moisdujs Typescript : Les types const title:string = 'Mois du JS'; const nbSlots:number = 3; let slotName:string = 'ES2015'; slotName = 3; // Error number is not a string slotName.any = 3; // Error const slots:Array<string> = ['ES2015', 'Tests', 'ESLint']; @XebiaFr @pgdejardin #moisdujs Typescript : Les classes class Slot { title:string; date:Date; constructor(title:string, date:Date) { this.title = title; this.date = date; } } const tsSlot:Slot = new Slot('Typescript', new Date('2016/06/14')); console.log(tsSlot.title); @XebiaFr @pgdejardin #moisdujs Typescript : Les enums enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } console.log(Week.Monday !== Week.Friday); // true console.log(Week.Monday == 0); // true and compile @XebiaFr @pgdejardin #moisdujs Typescript : Les interfaces interface Canid { name:string bark():string } class Dog extends Animal implements Canid { name:string; bark():string { return 'woaf'; } } @XebiaFr @pgdejardin #moisdujs Typescript : Les interfaces interface Canid { name:string bark():string } class Dog extends Animal implements Canid { name:string; bark():string { return 'woaf'; } } @XebiaFr @pgdejardin #moisdujs Typescript : Le 'any' ou Typage graduel let anyVariable:any = 'a variable'; anyVariable = 1; let husky:Husky = new Husky('Toto'); let pug:Pug = new Pug('Titi'); pug = husky; // Error properties from Pug missing in Husky let jokerDog:any = husky; pug = jokerDog; // OK @XebiaFr @pgdejardin #moisdujs Typescript : Les soucis... ● Transpilation (Pour le moment ca n'en est pas un car obligé de transpiler pour ES6) ● Vitesse de compilation sur les gros projets ● Les fichiers de définitions @XebiaFr @pgdejardin #moisdujs Typescript : Conclusion ● ● ● ● ● @XebiaFr Utilisable avec du javascript (migration progressive) Auto-completion avec IDE plus forte qu'en javascript ES2015-2016 !!! Refactoring plus simple qu'en javascript Simple à apprendre @pgdejardin #moisdujs Merci ! Questions ? @XebiaFr @pgdejardin #moisdujs Rejoignez-nous ! [email protected] blog.xebia.fr