Comment j'ai migré flaming.codes de Next.js à Qwik

Mon périple de deux semaines pour migrer flaming.codes de Next.js à Qwik et Qwik City

Pour commencer : comment tout cela s'est terminé

Si vous souhaitez passer toute l'histoire et simplement voir le résultat, voici en résumé :

  • flaming.codes a été réécrit entièrement (et sera désormais appelé v2) et utilise désormais Qwik et Qwik City comme frameworks de base, alors qu'auparavant c'était Next.js
  • J'ai supprimé toutes les dépendances liées au CMS tiers et à la couche de mise en cache et j'héberge tout le contenu dans le dépôt Github de cette PWA (Progressive Web App)
  • J'ai fait cela car je me suis rendu compte que maintenir toute la pile technologique de la v1 de flaming.codes était trop de travail - la goutte d'eau a été lorsque j'ai dû mettre à jour le CMS (Sanity) et que j'aurais de toute façon dû réécrire certaines choses
  • Le composant de traduction de la v1, qui impliquait un analyseur personnalisé de documents et la traduction via Google Traduction, a été remplacé par du contenu en markdown pur et OpenAI's GPT-4, respectivement
  • Je n'ai pas encore implémenté la fonctionnalité TTS (Texte vers Parole), mais je le ferai dans un avenir proche en utilisant le modèle Whisper d'OpenAI
  • flaming.codes est toujours hébergé sur Vercel, mais utilise maintenant Edge Functions pour servir le site, au lieu de Build Output API, puisqu'il n'y a actuellement pas d'adaptateur de déploiement fourni par Qwik City
  • Le design a également été mis à jour et prend désormais en charge le mode sombre et le mode clair en utilisant les Windy Radix Colors pour avoir les couleurs Radix disponibles comme classes Tailwind

Page d'accueil de flaming.codes version 2

Le CMS est parti, vive le CMS

La raison principale pour laquelle j'ai écrit la v2 de flaming.codes était de réduire les dépendances aux services :

  • supprimer le CMS (et son CDN) et gérer ainsi qu'héberger tout le contenu (articles, catégories, ressources, etc.) directement dans le dépôt, qui sera également open-source
  • dans le cadre de cette transition, supprimer la couche de mise en cache pour le contenu du CMS, car elle n'est plus nécessaire
  • remplacer l'utilisation de Google Traduction ainsi que de la synthèse vocale de Microsoft par des API d'OpenAI

Se passer d'un CMS puissant comme Sanity et son générateur de requêtes dynamiques a un coût : celui de devoir implémenter une gestion de contenu (légère) moi-même. Je ne veux pas avoir à me soucier de mettre à jour et de maintenir une pièce aussi centrale du projet. Mon objectif est que cette solution fonctionne même si je n'écris pas d'article pendant un an, car la seule exigence devrait être d'ouvrir le dépôt, d'écrire un article puis de simplement pousser les changements sur la branche principale pour déclencher un nouveau déploiement.

Vous pouvez inspecter le répertoire /cms à la racine du projet sur GitHub pour voir le code source par vous-même. Ça fonctionne assez bien, c'est simple et complètement autonome, aucun compte supplémentaire et connexion à un CMS n'est requis. L'expérience de sortie est maintenant en fait plus puissante qu'avant, car je peux maintenant utiliser le Markdown pour tout le contenu, ce qui est beaucoup plus facile à écrire et à maintenir que l'éditeur personnalisé de Sanity. J'ai ajouté une option de rechargement en direct pour le script de l'éditeur, de sorte que je puisse voir les modifications en temps réel - si je le souhaite même pour plusieurs langues à la fois.

Je donnerai plus de détails sur le CMS dans un autre article.

Pourquoi j'ai choisi Qwik et Qwik City au lieu de Next.js

Qwik et son framework Full-Stack appelé « Qwik City » m'ont paru très intrigants dès le début : le chargement à la demande de tout JS automatiquement jusqu'à ce qu'il soit réellement nécessaire sans aucune hydratation. Dans le contexte de flaming.codes, les gains de cette architecture sont minimes, car mon site est, dans son essence, un blog. Plus un site web comporte de composants et d'interactions, plus les améliorations apportées par l'utilisation de Qwik sont importantes. Cependant, j'étais curieux et voulais acquérir une expérience de première main avec.

i18n dans Qwik comparé à Next.js

flaming.codes est traduit en 14 langues, y compris certaines de droite à gauche. Lorsque j'ai jeté un premier coup d'œil à Qwik au début de 2023 (environ 10 mois avant la réécriture effective de la v2), j'ai senti qu'il n'y avait pas vraiment de solution pour l'i18n, et mes efforts au-delà de quelques tests initiaux se sont estompés.

En y regardant à nouveau en décembre, qwik-speak était la solution requise pour activer les traductions dans flaming.codes, alors j'ai dépoussiéré l'ancienne base de code et démarré la réécriture.

Un nouveau traducteur

L'ancienne pile utilisait l'API Google Traduction, qui m'a bien servi, mais l'ensemble du composant venait avec une certaine complexité :

  • le contenu dans la langue originale était récupéré à partir du CMS Sanity, analysé et divisé en morceaux intermédiaires
  • Chaque morceau était ensuite traduit dans les langues cibles disponibles
  • Les morceaux traduits étaient reconstruits de manière à ce que le contenu original, y compris le formatage, soit restauré et disponible pour le Frontend

Cela a assez bien fonctionné, mais le code était relativement difficile à lire et à maintenir.

flaming.codes utilise maintenant OpenAI pour traduire tout le contenu. Toute la configuration est beaucoup plus simple :

  • un nouvel article est rédigé en Markdown pur
  • l'article est envoyé à OpenAI et traduit dans son intégralité
  • Les LLM sont assez intelligents pour ne traduire que les parties pertinentes, mais pas par exemple l'intégralité du frontmatter (un indicatif donne des directives au LLM concernant les champs qui ne devraient pas être soumis à la procédure)

Déploiement sur Vercel

Qwik City pourrait être exporté en tant que site statique (SSG), mais cela signifierait que je ne pourrais pas utiliser de points de terminaison dynamiques, donc flaming.codes utilise l'adaptateur « Vercel Edge » pour continuer le déploiement et l'hébergement via Vercel. J'aimerais que l'« API de sortie de build » de Vercel soit également disponible en tant qu'adaptateur, mais pour l'instant c'est suffisant.

flaming.codes utilisait auparavant l'API de sortie de build, ce qui signifiait que le code côté serveur utilisait des API Node.js - sur Vercel Edge, cela n'est plus possible, car c'est un mélange quelque peu étrange et déroutant d'API Web et Node.js. Cela m'a obligé à réécrire certains composants pour la compatibilité.

IA et transparence

Bien que non prêt pour la sortie initiale de la v2, je mettrai à jour les propriétés des métadonnées pour les nouveaux articles afin d'avoir plus d'informations sur quels aspects d'un article ont été créés en utilisant l'IA.

Dans le même mouvement, je rendrai également publique l'analyse du site pour augmenter encore la transparence. flaming.codes utilise Plausible.io, un service d'analyse respectueux de la vie privée pour l'agrégation de l'utilisation de base.

Un nouveau design

Héro de l'article de flaming.codes version 2

Dans le cadre de cette réécriture complète, j'ai également mis à jour un peu le design. C'est similaire sur la plupart des pages, mais avec une touche de fraîcheur.

Champs de métadonnées d'article de flaming.codes version 2

De nouvelles couleurs + modes clair et sombre

Grâce aux Windy Radix Colors, le support pour les modes clair et sombre a été facile à implémenter car la bibliothèque fournit toutes les variantes de couleurs pour les deux modes.

Page de tous les posts de flaming.codes version 2 en mode sombre

Page de tous les posts de flaming.codes version 2 en mode clair

J'utilise maintenant la palette Radix Color comme plugin Tailwind, qui vient avec une sélection soignée de variantes de couleur ainsi qu'un support facile pour un mode clair/sombre. J'ai également changé pour les icônes Lucide car elles sont disponibles via une bibliothèque pour Qwik. Pour comparaison, voici quelques captures d'écran de l'ancien design :

Page d'accueil de flaming.codes version 1

Héro de l'article de flaming.codes version 1

Conclusion et prochaines étapes

La v1 de flaming.codes m'a très bien servi depuis son lancement initial, mais je sentais que la pile technologique devait être simplifiée en ce qui concerne les dépendances vis-à-vis d'autres services.

Il m'a fallu environ deux semaines pour terminer la réécriture. La gestion du contenu sera désormais beaucoup plus simple et m'aidera également à éviter des coûts excessifs.

La version 2 de flaming.codes n'a pas atteint la parité des fonctionnalités avec la v1 pour son lancement, mais j'ajouterai les fonctionnalités manquantes dans les semaines à venir, telles que le bouton j’aime / je n’aime pas ou la fonctionnalité TTS (Texte vers Parole).