Ciao WordPress, Hello JAMstack
Pour ceux qui l’ignorent, JAMstack est l’acronyme de JavaScript, APIs et Markup. Cela veut dire que contrairement à un CMS comme WordPress, le serveur web ne fait que livrer des fichiers statiques pré-compilés. Cependant, cela ne veut pas forcement dire que le site est statique, il y a du JavaScript et ce dernier est en mesure d’interagir avec des API (donc récupérer des données etc). Voyons les raisons de mon choix et le dessous des cartes techniques !
Comme on risque de beaucoup parler de statique et de JAMstack, si vous voulez creuser un peu plus, de très bonne ressources existent à ce sujet. Je vous conseille JAMstack.org [en] ou un article de JAMstatic [fr].
Va, je ne te hais point
Quitter WordPress, on en parlait récemment chez MyLittleBlog. Ce n’est pas une idée nouvelle et ces dernières années, de très nombreux sites et blogs ont migré vers des générateurs de sites statiques.
En ce qui me concerne, je suis intimement convaincu que la meilleure technologie est celle qui est adaptée au projet.
Ainsi, WordPress, de moteur de blog, est petit à petit devenu un CMS généraliste. On peut l’utiliser pour tout. J’en suis d’ailleurs très satisfait en tant que CMS. Preuve en est, j’ai récemment publié un article sur le blank theme que j’utilise pour mes projets WordPress.
Mais alors, si j’en suis si satisfait, pourquoi donc le quitter ? Soyons honnête, je suis avant tout un développeur JavaScript. À ce titre, cette JAMstack me faisait de l’œil. Pourquoi avoir recours à PHP si je n’en ai pas besoin ?
En outre, j’ai été confronté à quelques difficultés de performances à cause de PHP et de WordPress. Bien que ce problème ait été réglé, j’avais mon argument technique pour justifier une migration.
De plus, j’accorde une importance toute particulière aux performances des sites que je conçois. Je m’attache à pré-compresser les assets dans les meilleurs formats possibles et à servir le plus performant selon les capacités du navigateur. J’ai d’ailleurs écrit à ce propos, Apache et Nginx le permettent aisément.
Cette livraison de fichiers dans les formats les plus adaptés était rendu assez difficile voir impossible par WordPress. Il existe bien des plugins de cache, mais les fichiers sont générés en HTML et ne sont pas pré-compressés. Les images quant à elles, ne peuvent être nativement supportées en WebP.
À l’inverse, la nature même de la JAMstack facilite grandement tout cela. Tout vit dans git et npm orchestre l’ensemble.
Enfin, dès début 2018, j’avais émis la volonté d’améliorer certains choses sur le blog. Pour cela, bénéficier d’une configuration de développement familière ne pouvait que m’aider à être plus productif.
La stack
Assez parlé des raisons de la migration, parlons de notre stack. Il existe de très nombreux générateurs de sites statiques. Je l’ai déjà dit, je fais principalement du JS, il était donc tout indiqué de choisir un générateur qui parle la même langue que moi.
J’avais en outre déjà eu une bonne expérience avec Hexo, c’est donc vers lui que je me suis naturellement dirigé. Il dispose en plus de nombreux plugins et il existe même une interface d’admin qui permet de le transformer en vrai CMS !
Comme je tenais à conserver le design du blog, je m’attèle tout d’abord à la création de mon thème. La doc est bien faite, il y a le choix dans les langages de templating et j’utilise EJS, qui est simplement du JavaScript.
Par ailleurs, côté perfs, je l’ai déjà mentionné, mais le statique permet beaucoup. Ainsi, le plugin hexo-yam me permet tout à la fois :
- de minifier le HTML, le CSS, le JavaScript le SVG, le XML et le JSON (activables séparémments),
- de pré-compresser en Gzip,
- de pré-compresser en Brolti.
Et tout cela se fait automatiquement à chaque deploy.
En revanche, vous l’avez peut-être compris, dans “générateur de site statique”, il y a site statique. Cela veut dire que sans API externe, point de recherche ni de commentaires. Alors là, ça ne va pas du tout. Certains utilisent Algolia et Disqus pour palier à cela, mais c’est abdiquer. Autant directement tout héberger chez Blogger ou Medium… Je respecte mes utilisateurs et je ne balancerai pas leurs données à tout va.
La recherche
Pour la recherche, c’est assez simple. Ce n’est que par flemme que nombre de devs mettent Algolia. Du côté de chez Hexo (et chez tous les générateurs dignes de ce nom), il y a un plugin fort pratique qui permet de générer un fichier JSON du contenu. Pas la peine de tout mettre : le titre, les tags et le premier paragraphe suffisent amplement pour une recherche tout à fait honnête.
Ce fichier, qui s’appelle chez moi api.json, est chargé de manière asynchrone et fait moins de 25k à transférer (en Brotli) pour mes ±150 articles. À moins d’avoir des miliers d’articles, cela me semble donc tout à fait viable, même sur le long terme.
Pour la recherche à proprement dite, le JS est l’homme qu’il vous faut. Les APIs natives IndexedDB vous permettent de stocker tout ça et de le requêter à votre guise. Il y a de plus pléthores de bibliothèques qui en facilitent la manipulation.
Tout cela me semblait cependant overkill pour une simple fonction de recherche. Je n’ai pas envie de gérer une base de données en locale, d’autant plus qu’elle va être amenée à changer dès qu’un nouvel article est posté. Mon choix s’est donc tourné vers un moteur de recherche in-memory du nom de Fuse.js.
Ce dernier m’avait déjà donné pleinement satisfaction sur d’autres projets. Il permet la fuzzy search – j’en ignore la traduction française littérale – ça veut dire qu’il comprend même s’il y a une légère faute de frappe – et pèse moins de 3,5Kb avant compression. Que demande le peuple ?
Les commentaires
Alors là, c’est le drame. Le plus simple est de balancer un Disqus, mais l’idée ne m’enchante guère.
Je n’étais pas séduit. Je voulais une solution simple, facile et auto-hébergée. On fait de la JAMstack pas vrai ? Je voulais donc une API de commentaires. Oui j’ai bien dit API, pas un script que j’intègre en haut de ma page à l’ancienne et qui fait ce qu’il veut.
Le but d’une API c’est que je soumets le commentaire via AJAX, et quand je veux récupérer des infos, je fais ma requêtes en asynchrone comme je l’entends, quand je l’entends, et l’API me retourne gentiment un JSON avec les infos demandées.
Je me suis donc fendu d’une solution du doux nom de Jamments. C’est super light, écrit en Node.js, il y a le choix de la base de données SQL que vous souhaitez utiliser (SQLite, MySQL, Maria, Postgre…), c’est Open Source et sous licence libre.
Il y a encore pas mal de boulot, alors n’hésitez surtout pas à me filer un coup de main, le monde vous en sera reconnaissant. Je vais certainement écrire un article dédié afin d’en parler dans de plus amples détails.
Avec cette API, mon blog peut donc recevoir et récupérer les commentaires et j’ai une liberté totale dans ma façon d’afficher ces derniers. Le code côté client est forcement un peu plus complexe puisque je souhaite permettre à mes visiteurs d’écrire certaines choses en Markdown (pratique pour le code et les liens).
Tout ça mérite encore un peu d’affinage, mais c’est en tout cas la solution que j’ai adoptée.
La migration
Aouch, c’est honnêtement là que le bas blesse. Sur WordPress, tous mes articles étaient écrits en HTML brut. Donc pour tout transférer, ça n’a pas été d’une grande simplicité. Pour un blog qui ne traite pas de code, à la rigueur ça aurait été facile, mais là, j’ai du mettre les mains dans le cambouis. Et pas qu’un peu.
Après import avec l’outil officiel, j’ai du balancer des grands coups de regex via sed dans tous les sens pour remplacer de très nombreuses choses. Côté blocs de code, j’utilisais le Prettify de Google. Mais j’ai décidé de changer pour highlight.js qui est plus léger, possède plus de thèmes…
On commence là par une syntaxe différente.
<!-- on passe de ça !-->
<pre class="prettyprint">
le code ici
</pre>
<!-- à ça en markdown !-->
```
le code ici
```
<!-- ou version HTML !-->
<pre><code>
le code ici
</code></pre>
Tous les exemples de code HTML que j’avais encodé en entitées HTML, il a fallu que je les ré-encode en HTML brut, sinon j’obtenais le rendu des entitées telles quelles. Pas cool.
Pourquoi ? Tout simplement parce qu’en HTML vous avez la possibilité de placer des caractères en HTML entities et ils auront le bon rendu à l’écran sans compter comme “vraies” balises. Mais en Md, après ces fameux triples “`”, vous affichez tout en brut.
En outre, même si le HTML est permis dans le Markdown, les espaces sont quand même interprétés, on a donc vite fait de se retrouver avec des <br>
et des <p></p>
vides dans tous les sens. Oui, j’aime bien revenir à la ligne et indenter mon code quand j’écris une liste, un tableau, ou un blockquote
.
De plus, dans la syntaxe Md, certaines choses ne sont pas supportée. À titre d’exemple, les tableaux Markdown sont assez simples et il n’est pas possible de créer des tableaux avec des colspan
ou rawspan
, comme celui de mon article sur les unités informatiques.
Fort heureusement, quand cela devient trop compliqué, un petit tag permet de dire à l’interpréteur Markdown que là, il cesse d’être le maître des lieux.
<p>Ici, tout est HTML brut</p>
Cela dit, ce n’est pas le genre de syntaxe qu’on a envie d’utiliser toutes les deux lignes. Donc on tente de tirer le maximum du Markdown.
Pour le blockquote
par exemple, j’aimais bien entourer l’ensemble d’une balise figure
et profiter de figcaption
pour sémantiquement lier ces deux éléments ; ainsi que l’explique cet article de A List Apart. Mes styles CSS s’appuyaient là-dessus pour afficher le tout bien proprement.
Cependant, Md ne le permet pas, donc j’ai du trouver une autre solution. J’ai ainsi pris le parti de faire suivre mon blockquote
de la balise cite
quand je veux attribuer la source. Le seul problème, c’est que cite
est censé contenir le titre d’une œuvre, pas le nom de quelqu’un ou d’un site internet. Cette fois, tant pis pour la sémantique, j’ai abdiqué.
> Talk is cheap. Show me the code
<cite>Linus Torvalds</cite>
Voyons quand même le positif, j’ai bien galéré, mais une fois que c’est en place, c’est plutôt cool d’écrire en Md, et c’est bien plus fluide que d’écrire en HTML, même si Emmet facilite bien le boulot.
Conclusion
J’ai bien lutté pour passer de WordPress a Hexo, forcément, le passage du HTML au Markdown n’a pas été une mince affaire. Si c’était à refaire, je m’y prendrais de manière différente.
Je créerais un script afin de récupérer l’ensemble des contenus bruts via l’API de WordPress, et les injecter directement dans leurs fichiers de destination, en enrobant le HTML entre {% raw %}
et {% endraw %}
afin de ne pas m’embêter à convertir une syntaxe en une autre.
De cette manière, pas de problèmes d’espaces, de paragraphes fantômes etc. Je n’aurais eu qu’à me soucier de passer d’un plugin de coloration syntaxique à l’autre. Évidemment, on se rend compte de ça une fois qu’on est à mi-chemin !
Je suis tout de même content d’avoir franchi le pas. C’est plaisant à l’usage, j’écris dans une syntaxe allégée depuis mon éditeur de code habituel, je dispose tout de même de toute la puissance de l’HTML au besoin et je build et deploy le tout d’un simple coup de CLI.
Commentaires
Rejoignez la discussion !