Polymer

Ce vendredi, j'ai testé Polymer. Depuis le temps qu'il me faisait de l'œil… Et bien, j'aime beaucoup. Contrairement à React qui m'a laissé de marbre, Polymer a réussi à me convaincre que AngularJS n'était pas le seul framework incontournable. Ce que j'ai fait, c'est suivre le tutorial, écrire mon propre posts-service afin qu'il renvoie des mocks en dur et écrire un composant reprenant le principe de mon précédent article : remplacer les avatar par des initiales colorées. Un très bon exercice qui m'a permis de chercher et trouver comment :

  • séparer styles, scripts et templates,
  • inclure un script externe,
  • passer des données d'un composant à l'autre

Ça va donner quelque chose dans ce genre :

/index.html
/components/nice-avatar
/components/nice-avatar/nice-avatar.html
/components/nice-avatar/nice-avatar.css
/components/nice-avatar/nice-avatar.js
/lib/(bower_components)

J'ai donc mes composants bower dans un dossier lib (je suis parti de yeoman-polymer). Je ne vais parler que du composant nice-avatar.

<html>  
<head>  
  …
  <link
    rel="import"
    href="scripts/components/nice-avatar/nice-avatar.html">
</head>  
<body>  
  <nice-avatar
    firstname="Georges"
    lastname="Abitbol"></nice-avatar>
</body>  
</html>  

On va d'abord voir le découpage du composant, le tutorial de Polymer ne montrant que des fichiers html contenant css, html et javascript, ce qui ne plait pas du tout à Sublime Text qui n'arrive plus à me colorer correctement la syntaxe.

<link rel="import" href="/lib/polymer/polymer.html">  
<script src="/lib/js-md5/js/md5.min.js"></script>  
<polymer-element  
  name="nice-avatar"
  attributes="firstname lastname">
  <template>
    <style>
      @import 'nice-avatar.css';
    </style>
    <span>{{initials}}</span>
  </template>
  <script src="nice-avatar.js"></script>
</polymer-element>  

Avec le projet du tuto, j'ai quelque chose qui ressemble plus à ça :

<template repeat="{{post in posts}}">  
  <nice-avatar
    firstname="{{post.firstname}}"
    lastname="{{post.lastname}}"></nice-avatar>
    …
</template>  

On peut voir qu'un script externe est chargé spécialement pour ce composant à l'aide de la balise <script> en dehors du composant. C'est un script ajouté au projet avec bower qui servira à calculer le hash md5.

Ensuite, on déclare notre composant, puis dans la balise style, au lieu de taper des css, on fait un import du fichier css qu'on a prélablement placé dans le même dossier. Et on peut quand même utiliser de l'interpolation ! C'est magique !

:host {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: {{ bg }};
  border-radius: 50px;
  line-height: 50px;
  text-align: center;
  color: white;
}

Ensuite, on écrit notre template, ici, ça change pas. Puis, au lieu de rédigier notre script en ligne, on insérer une balise pointant vers un script situé dans le même dossier lui aussi.

Polymer({  
  ready: function () {
    this.initials = makeInitials(this.firstname, this.lastname);
    this.bg = makeBg(this.firstname, this.lastname);
  },
  firstnameChange: function (newVal) {
    this.initials = makeInitials(this.firstname, this.lastname);
    this.bg = makeBg(this.firstname, this.lastname);
  },
  lastnameChange: function (newVal) {
    this.initials = makeInitials(this.firstname, this.lastname);
    this.bg = makeBg(this.firstname, this.lastname);
  }
});

function makeInitials (firstname, lastname) {  
  return firstname.substr(0,1).toUpperCase() +
    lastname.substr(0,1).toUpperCase();
}

function makeBg (firstname, lastname) {  
  return '#' + md5(firstname + lastname).substr(0,6);
}

La méthode md5 est donc accessible et permet de calculer un hash du prénom/nom et ainsi de générer une couleur hexa qui viendra modifier la valeur dans le fichier css.

En plus de ça, j'ai découvert qu'il était possible de combiner tous les fichiers d'un projet en un seul grâce à Vulcanize. C'était une interrogation qu'il me restait par rapport aux web components. En effet, une webapp finit par compter ses composants par dizaines et sans concaténation, on se retrouve à perdre plus de temps à demander des fichiers qu'à les charger vraiment. Je ne sais pas quelle sera la réponse du w3c à cette problématique, mais je sais au moins que Polymer en apporte une.

Hadrien

Hi, I'm a french Javascript Lead Developer, Web Architect from Toulouse, France. I've worked for 12 years for many projects with YUI, AngularJS, Aurelia.io and now React and React native.

Toulouse, France https://hadrien.eu