Come ho migrato flaming.codes da Next.js a Qwik

Il mio viaggio di due settimane nella migrazione di flaming.codes da Next.js a Qwik e Qwik City

Prima di tutto: come è andata a finire

Se vuoi saltare tutta la storia e vedere solo il risultato, ecco qui:

  • flaming.codes è stato riscritto da zero (d'ora in poi sarà chiamato v2) e ora utilizza Qwik e Qwik City come suo framework di base, precedentemente usava Next.js
  • Ho rimosso tutte le dipendenze relative al CMS di terze parti e allo strato di caching e ora ospito tutto il contenuto nel repository di Github di questa PWA (Progressive Web App)
  • Ho fatto ciò perché ho notato che mantenere l'intero stack della v1 di flaming.codes era troppo lavoro - la goccia che ha fatto traboccare il vaso è stata quando ho dovuto aggiornare il CMS (Sanity) e avrei dovuto comunque riscrivere alcune cose
  • Il componente di traduzione v1, che coinvolgeva un parser personalizzato di documenti e la traduzione tramite Google Translate, è stato sostituito da contenuti in puro markdown e GPT-4 di OpenAI, rispettivamente
  • Non ho ancora implementato la funzionalità TTS (Text-to-Speech), ma lo farò nel prossimo futuro utilizzando il modello Whisper di OpenAI
  • flaming.codes è ancora ospitato su Vercel, ma ora utilizza Edge Functions per servire il sito, invece che l'API di Output di Costruzione, poiché attualmente non è fornito alcun adattatore per la distribuzione da parte di Qwik City
  • Il design è stato anche aggiornato e ora supporta sia la modalità chiara che scura utilizzando Windy Radix Colors per avere i colori Radix disponibili come classi Tailwind

flaming.codes versione 2 pagina iniziale

Il CMS se ne è andato, lunga vita al CMS

La ragione principale per cui ho scritto la v2 di flaming.codes era ridurre le dipendenze dai servizi:

  • rimuovere il CMS (e il suo CDN) e gestire nonché ospitare tutto il contenuto (post, categorie, asset, ecc.) direttamente nel repository, che sarà inoltre aperto al pubblico
  • come parte di questa transizione, eliminare lo strato di caching per i contenuti del CMS, poiché non è più necessario
  • sostituire l'uso di Google Translate e del text-to-speech di Microsoft con le API di OpenAI

Passare da un CMS potente come Sanity e il suo costruttore di query dinamico ha il costo di dover implementare da solo una gestione dei contenuti (leggera). Non voglio preoccuparmi di dover aggiornare e mantenere un pezzo così centrale del progetto. Il mio obiettivo è avere questa soluzione funzionante anche se non scrivo un post per un anno, perché l'unico requisito dovrebbe essere aprire il repository, scrivere un articolo e poi semplicemente fare push dei cambiamenti su main per innescare un nuovo deploy.

Puoi ispezionare la directory /cms alla radice del progetto su GitHub per vedere il codice sorgente. Funziona abbastanza bene, è semplice e completamente autonoma, nessun account extra e accesso per un CMS richiesto. L'esperienza di uscita è ora effettivamente più potente di prima, poiché posso ora utilizzare Markdown per tutto il contenuto, che è molto più facile da scrivere e mantenere rispetto all'editor personalizzato di Sanity. Ho aggiunto un'opzione di ricarica in tempo reale per l'esecuzione dello script dell'editor, così posso vedere le modifiche in tempo reale - se voglio anche per più lingue contemporaneamente.

Approfondirò il discorso del CMS in un post separato.

Perché ho scelto Qwik e Qwik City invece di Next.js

Qwik e il suo Framework Full-Stack chiamato "Qwik City" mi sono sembrati molto interessanti fin dall'inizio: caricamento pigro di qualsiasi JS automaticamente fino a quando non è effettivamente necessario senza alcuna idratazione. Nel contesto di flaming.codes, i vantaggi di questa architettura sono in calo, dato che il mio sito è, nel suo nucleo, un blog. Più componenti e interazioni ha un'app web, maggiori sono i miglioramenti che derivano dall'uso di Qwik. Tuttavia, ero curioso e volevo acquisire un'esperienza diretta con esso.

i18n in Qwik rispetto a Next.js

flaming.codes è tradotto in 14 lingue, comprese alcune da destra a sinistra. Quando ho dato un'occhiata per la prima volta a Qwik all'inizio del 2023 (circa 10 mesi prima di fare il vero e proprio riscritto v2), ho sentito che non c'era una vera soluzione per i18n e i miei sforzi oltre alcuni test iniziali si sono affievoliti.

Riguardandolo a dicembre, qwik-speak era la soluzione necessaria per abilitare le traduzioni in flaming.codes, quindi ho rispolverato il vecchio codice e dato il via alla riscrittura.

Un nuovo traduttore

Il vecchio stack utilizzava l'API Google Translate, che mi ha servito bene, ma l'intero componente era venuto con una certa complessità:

  • i contenuti nella lingua originale venivano prelevati dal CMS di Sanity, analizzati e divisi in blocchi intermedi
  • Ogni blocco veniva poi tradotto nelle lingue di destinazione disponibili
  • I blocchi tradotti venivano ricostruiti in modo che il contenuto originale, incluse le formattazioni, venisse ripristinato e disponibile per il frontend

Funzionava abbastanza bene, ma il codice era relativamente difficile da leggere e mantenere.

flaming.codes ora utilizza OpenAI per tradurre tutto il contenuto. L'intera configurazione è molto più semplice:

  • si scrive un nuovo articolo in puro Markdown
  • l'articolo viene inviato a OpenAI e tradotto interamente
  • i LLM sono abbastanza intelligenti da tradurre solo le parti rilevanti, ma non ad esempio l'intero frontmatter (un prompt fornisce indicazioni all'LLM su quali campi non dovrebbero essere sottoposti alla procedura)

Deployment su Vercel

Qwik City potrebbe essere esportato come un sito statico (SSG), ma questo significherebbe che non potrei usare endpoint dinamici, quindi flaming.codes sta usando l'adattatore "Vercel Edge" per il deployment e l'hosting continuati tramite Vercel. Mi piacerebbe che "l'API di Output di Costruzione" di Vercel fosse anche disponibile come adattatore, ma per ora è sufficiente.

flaming.codes precedentemente utilizzava l'API di Output di Costruzione, il che significava che il codice lato server utilizzava API di Node.js - su Vercel Edge, questo non è più possibile, poiché è una miscela alquanto strana e confusa di API Web e Node.js. Questo mi ha richiesto di riscrivere alcuni componenti per la compatibilità.

AI e trasparenza

Anche se non pronto per il rilascio iniziale della v2, aggiornerò i metadati delle proprietà per i nuovi articoli per avere più informazioni su quali aspetti di un articolo sono stati creati utilizzando l'AI.

Con la stessa mossa, renderò inoltre pubblica l'analitica del sito per aumentare ulteriormente la trasparenza. flaming.codes utilizza Plausible.io, un servizio di analitica rispettoso della privacy per l'aggregazione dell'uso di base.

Un nuovo design

flaming.codes versione 2 eroe dell'articolo

Come parte della riscrittura completa ho anche aggiornato un po' il design. È simile nella maggior parte delle pagine, ma con una nuova mano di vernice.

flaming.codes versione 2 campi metadati dell'articolo

Nuovi colori + modalità chiara e scura

Grazie a Windy Radix Colors, il supporto per la modalità chiara e scura è stato facile da implementare poiché la libreria fornisce tutte le varianti di colore per entrambe le modalità.

flaming.codes versione 2 pagina di tutti i post in modalità scura

flaming.codes versione 2 pagina di tutti i post in modalità chiara

Adesso sto utilizzando la palette di Radix Color come un plugin di Tailwind, che viene fornito con una selezione attenta di varianti di colore e supporto facile per una modalità chiaro/scuro. Ho anche passato alle Lucide Icons poiché sono disponibili tramite una libreria per Qwik. Per confronto, ecco alcuni screenshot del vecchio design:

flaming.codes versione 1 pagina iniziale

flaming.codes versione 1 eroe dell'articolo

Conclusioni e cosa c'è dopo

La v1 di flaming.codes mi ha servito molto bene dal suo lancio iniziale, ma sentivo che lo stack doveva essere semplificato verso le dipendenze da altri servizi.

Ci ho messo circa due settimane per completare la riscrittura. La gestione dei contenuti d'ora in poi sarà molto più semplice e mi aiuterà anche ad evitare costi eccessivi.

La versione 2 di flaming.codes non ha raggiunto la parità di funzionalità con la v1 per il suo lancio, ma aggiungerò le funzionalità mancanti nelle prossime settimane, come il pulsante di mi piace/non mi piace o la funzionalità TTS (Text-to-Speech).