Transformation d’une WebApp en application desktop

Un POC réalisé avec WordPress, NodeJS, Riot et Electron.


Le pôle WordPress a réalisé un POC qui transforme une web app en application desktop avec Electron. Le besoin de notre client est de pouvoir télécharger le contenu des présentations administrées depuis un back-office et tous les fichiers médias associés pour naviguer hors ligne.

Electron

Un back-office WordPress permet l’édition des présentations et la mise à disposition d’une API pour la web application. Nous avions écarté la solution WPAppKit car elle est vouée à un usage desktop, et les technologies de mode hors connexion AppCache et ServiceWorker, par leurs limitations, ne permettent pas de supporter la quantité de données à stocker. Un système de fichiers, et donc un serveur, était nécessaire, et pour qu’il soit embarqué et simple à installer, nous nous sommes tournés vers Electron qui embarque un NodeJS.

L’application est développée avec des technologies front-end, soutenue d’un proxy en NodeJS qui livre les fichiers depuis le cache, et stocke les données depuis WordPress lorsque le cache expire ou n’est pas disponible. L’application est vouée à fonctionner également dans le navigateur, mais sans le mode hors-ligne.

Débuter avec Electron est relativement simple et ne nécessite pas d’adaptation particulière sinon un fichier main.js (le serveur), et un fichier package.json pour les informations concernant la build et les dépendances. D’ailleurs, je n’ai que deux dépendances locales déclarées : electron, et electron-builder qui simplifie grandement le packaging des exécutables distribuables. L’application embarquée est donc strictement la même que l’application desktop : on peut ouvrir l’index.html dans son navigateur et tout fonctionne aussi bien. Voici un aperçu de l’arborescence :

Article Nicolas Desktop

Exécutée dans le navigateur, la web app appelle directement WordPress et ne gère pas le mode hors ligne. Embarquée dans Electron, et donc exécutée en tant qu’application desktop, la web app communique exclusivement avec le serveur via le protocole ICP (inclu nativement dans Electron). Seul celui-ci est en mesure d’appeler WordPress, et lorsque l’utilisateur demande le téléchargement des données de la page en cours, alors le serveur stocke le JSON retourné par WordPress, télécharge les médias, et remplace toutes URLs (de médias) contenues dans le JSON contre des URLs locales.

Article Nicolas Desktop2

Riot

Nous avons choisi Riot, un framework émergent, qui n’est pas voué à exploser ni à concurrencer les grands comme React, Angular ou Polymer, mais qui rassemble beaucoup de leurs idées dans un outil très léger (9kb minifié+gzip) et très accessible. Il embarque son propre router et favorise l’écriture de JavaScript natif ou jQuery grâce à une syntaxe peu opinionated. Pour avoir déjà joué avec Angular (v1), React, Vue, Polymer et Meteor, je constaste que son empreinte sur le code est minime, et le confort de développement est pour l’instant bien au-dessus. Sans-doute déconseillé pour une application d’envergure, Riot convient cependant parfaitement aux petites et moyennes web apps.

Une application Riot s’organise en composants indépendants et réutilisables. Ils embarquent leur logique, et leur style, même si nous avons préféré rassembler les styles dans un modèle plus classique de feuille globale. On monte et démonte les composants selon les nécessités, le data-binding est très basique et sert de helper, et il est d’usage de déclencher manuellement la mise à jour du DOM.

Le premier exemple de composant qu’on rencontre sur le site de Riot est très explicite :

<todo>
  <h3>TODO</h3>
  <ul>
    <li each={ item, i in items }>{ item }</li>
  </ul>
  <form onsubmit={ handleSubmit }>
    <input>
    <button>Add #{ items.length + 1 }</button>
  </form>
 
  this.items = []
  handleSubmit(e) {
    var input = e.target[0]
    this.items.push(input.value)
    input.value = ''
  }
</todo>

Il n’en faut pas plus pour créer une todo list. Riot permet bien entendu d’imbriquer les composants, de faire des boucles et des conditions. À l’intérieur des accolades, on utilise des expressions purement JavaScript, dont le résultat est affiché (ou retourné dans le cas d’un élément de structure).

Etc.

Quant au build tool, on expérimente avec le Makefile, pour descendre encore d’un niveau et optimiser au plus les temps de compilation. GNU Make a nativement un comportement de watcher, il vérifie l’ancienneté des sources avant de construire les cibles, et il permet l’exécution de scripts bash, tout comme NPM scripts, mais avec plus de libertés encore dont l’usage de variables. L’astuce supplémentaire a été de séparer la compilation de Bootstrap et du style de l’application, qui se partagent uniquement les variables. Le fichier main emprunte aussi aux sources Bootstrap le mixin de media-queries pour préserver une cohérence dans leurs déclarations. Pour résultat il faut souvent moins d’une seconde, parfois deux, à partir du moment où la commande est lancée pour que les modifications soient disponibles.

Article Nicolas Desktop3

 

Et voici un l’extrait du Makefile qui compile les CSS :

# Concat & minify styles
app/public/css/bootstrap.css: sources/scss/_variables.scss
@ echo "› Building $@:"
@ node-sass --output-style=compressed sources/scss/bootstrap.scss -o app/public/css/ --source-map app/public/css/
@ echo "› Done."

app/public/css/app.css: sources/scss/*.scss
@ echo "› Building $@:"
@ node-sass --output-style=compressed sources/scss/app.scss -o app/public/css/ --source-map app/public/css/
@ echo "› Done."

Pour conclure

Réaliser une application desktop avec Electron était beaucoup plus simple que je l’imaginais. De même, Riot a été un allié important qui m’a fait gagner beaucoup de temps, alors même que je n’avais aucune expérience dessus, car je n’ai pas eu à me poser de questions d’architecture. La seule difficulté a été la conception du proxy/cache qui permet le mode hors ligne et la mise à jour des ressources depuis WordPress. Bien qu’il ait fallu moins de 15 minutes pour lancer la web app en desktop avec Electron, la compréhension du workflow de build complet a finalement pris une journée.

Ressources

Publié le par Nicolas Torres

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *