Faites de l’ES2015 et ES2016 dans votre navigateur, avec JSPM

Il est bien entendu que tout ce qui va suivre ne doit pas se retrouver en production (aprĂšs vous faites comme vous voulez).

Préparation de votre environnement

Tout d’abord vous avez vesoin de JSPM http://jspm.io/ qui est un gestionnaire de package s’appuyant sur la gestion des modules façon ES6 (ES2015). JPSM peut utiliser les packages npm mais aussi utiliser des projets sous GitHub.

Donc, dans un 1er temps, installez JSPM: npm install jspm -g (prĂ©cĂ©dĂ© de sudo pour les Mac users). Ensuite, crĂ©ez un rĂ©pertoire, et une fois “dans” ce rĂ©pertoire, tapez la commande suivante:

	jspm init

JSPM va vous poser une série de questions:

	Package.json file does not exist, create it? [yes]:
	Would you like jspm to prefix the jspm package.json properties under jspm? [yes]:
	Enter server baseURL (public folder path) [./]:
	Enter jspm packages folder [./jspm_packages]:
	Enter config file path [./config.js]:
	Configuration file config.js doesn't exist, create it? [yes]:
	Enter client baseURL (public folder URL) [/]:
	Do you wish to use a transpiler? [yes]:
	Which ES6 transpiler would you like to use, Babel, TypeScript or Traceur? [babel]:

Normalement, rĂ©pondez avec les valeurs par dĂ©faut. Ce qui est important c’est la derniĂšre question Ă  propos du transpiler, choisissez bien Babel (pour ce tuto lĂ ).

A la question Enter server baseURL (public folder path) [./]: vous pouvez répondre par exemple public si votre webapp est dans un sous répertoire public, sinon laissez tel quel.

Vous aurez besoin d’un serveur http (j’utilise http-server: https://www.npmjs.com/package/http-server).

Création de notre page index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ES2015-2016</title>
</head>
<body>
	<h1></h1>
  <script src="jspm_packages/system.js"></script>
  <script src="config.js"></script>
  <script>
    System.import("main");
  </script>
</body>
</html>

La ligne System.import("main"); signifie que nous allons charger main.js. Allons donc créer nos script façon ES2015.

Création de main.js et message.js

Créez un 1er fichier message.js:

class Message {
	constructor(label) {
		this.label = label
	}
}

export default Message

Puis créez un 1er fichier main.js:

import Message from './message'

let message = new Message("Hello world!");

document.querySelector('h1').innerHTML = message.label;

Lancez votre serveur http (dans mon cas http-server). Puis ouvrez votre webapp, et la magie s’opùre: vous obtenez un titre Hello World!.

Et maintenant que du code ES2015 (ou ES6) tourne dans votre navigateur, allons plus loin pour faire de l’ES2016 (ou ES7).

Modifier le fichier de Configuration

Dans votre répertoire, JSPM a créé un fichier config.js qui débute de cette façon:

System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ]
  },

Modifiez le de la maniĂšre suivante:

System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system",
      "es7.classProperties",
      "es7.decorators"
    ]
  },

es7.classProperties

L’option es7.classProperties de Babel va nous permettre de modifier notre classe Message de la maniùre suivante (dans le fichier message.js):

class Message {
	label = "Hello World!"
	constructor() {}

	display() {
		document.querySelector('h1').innerHTML = this.label;
	}
}

export default Message

Il devient donc possible de définir les propriétés de la classe en dehors du constructeur (comme en TypeScript).

Modifiez votre fichier main.js comme ceci:

import Message from './message'

let message = new Message();

message.display()

Vous pouvez recharger votre page pour vérifier que votre code fonctionne toujours.

es7.decorators

L’option es7.decorators de Babel va nous permettre de “dĂ©corer” nos classes et leurs mĂ©thodes.

1er décorateur

Par exemple, Ă©crivons un 1er dĂ©corateur: (dans notre fichier message.js, mais ça sera bien ensuite de l’externaliser)

function Before(text) {
  return function(target, nname, descriptor) {
    let originalFunction = descriptor.value;
    descriptor.value = function(...args) {
      args[0] = text + args[0];
      return originalFunction.apply(this, args);
    }
  }
}

Puis modifiez la classe Message:

class Message {
	@Before("+++:")
	display(message) {
		document.querySelector("h1").innerHTML = message;
	}
}

export default Message

Puis modifiez main.js:

import Message from './message'

let message = new Message();

message.display("Hello World!!!")

Vous pouvez recharger votre page pour vérifier que votre code fonctionne toujours. Cette fois ci vous obtiendrez un titre qui devrait ressemblait à ceci: +++:Hello World!!!

Les dĂ©corateurs nous permettent donc de modifier les comportements des mĂ©thodes (attention ils s’exĂ©cutent au chargement des classes).

Un dernier pour la route: un décorateur de classe:

Ajoutez ce décorateur:

function Testable (target) { target.testable = true }

Puis modifiez la classe Message comme ceci en lui ajoutant le dĂ©corateur @Testable (sans parenthĂšse car nous n’avons pas utilisĂ© de paramĂštre):

@Testable
class Message {
	@Before("+++:")
	display(message) {
		document.querySelector("h1").innerHTML = message;
	}
}

export default Message

Cette fonctionnalitĂ© permettant de dĂ©corer les classes et les mĂ©thodes est particuliĂšrement intĂ©ressante pour simplifier le code. Elle est dĂ©jĂ  largement utilisĂ©e dans des frameworks en cours de dĂ©veloppement tels Aurelia ou Angular 2. Par contre attention, les spĂ©cifications ne sont pas encore arrĂȘtĂ©es, ce n’est donc Ă  utiliser qu’à titre expĂ©rimental.

Builder tout ça

Si vous souhaitez builder l’application, c’est tout simple:

jspm bundle-sfx main

Cela va produire 2 fichiers: build.js et build.js.map

Modifiez votre page index.html comme ceci:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ES2015-2016</title>
</head>
<body>
	<h1></h1>
  <script src="build.js"></script>
</body>
</html>

Dans un prochain article, je vous montrerais comment utiliser les dĂ©corateurs avec babel-node et comment il est possible de simplifier le code d’une application ExpressJS.

@+

blog comments powered by Disqus

Related posts