Strumenti per il rinascimento server side

Pubblicato il 27-03-2022 | 5 min di lettura

Di recente ho realizzato che usare una libreria come Vue per aggiungere interattività a del contenuto generato da un CMS spesso sembra.. un po' esagerato.

Ellipse

Perché usare qualcosa come Vue

Vue, insieme alle varie alternative più corporate, come React e Angular, nasce per risolvere alcuni problemi di interattività. Queste librerie ci permettono di avere un approccio dichiarativo per rappresentare informazioni. Queste informazioni possono essere già presenti nel contesto, e quindi provenire da file statici, come per esempio file JSON o Markdown. In alternativa, possiamo anche includere informazioni in modo asincrono usando delle API: questo pattern ci permette di disaccoppiare il front-end dal back-end, e può essere molto utile in caso i dati vengano consumati da altri canali.

Una volta che portiamo dati all'interno di Vue possiamo facilmente dichiararne il comportamento, aggiungendo animazioni, controlli e logiche di accesso, fino ad arrivare a fornire funzioni di navigazione che sostituiscono il classico pattern richiesta / risposta di pagine complete in html.

Complessità di una Single Page Application

Il pattern descritto qua sopra si chiama "SPA": Single Page Application. Quando il browser arriva alla nostra SPA, noi gli serviamo un file html piuttosto vuoto, che però include il javascript della nostra applicazione. Questo javascript porta con sé il contenuti statico, le informazioni di navigazione e tutta la logica della nostra app.

Un approccio SPA ad un sito tradizionale ha alcuni vantaggi. Lo sviluppatore può usufruire di un'ottima esperienza di sviluppo nel caso ci siano particolari logiche per l'interazione, come per esempio funzioni di ricerca, filtri e transizioni tra le pagine. Per un utente dopo il primo caricamento l'applicazione è più veloce - o almeno sembra così.

Questo approccio ha anche alcuni problemi. La flessibilità di uno strumento come Vue significa che per progetti complessi può essere difficile implementare delle convenzioni. Inoltre a livello tecnico una SPA non gestisce molto bene il crawling fatto dai motori di ricerca, che è più calibrato per un sito "standard".

Per ovviare a queste limitazioni negli anni sono emerse delle meta-framework basate sulle librerie più popolari. Per Vue si può usare Nuxt o Gridsome, mentre per React una delle alternative è Next. Queste soluzioni permettono di usare tutti i vantaggi di un approccio dichiarativo, dando la possibilità di creare diversi tipi di applicazioni. Con Nuxt per esempio possiamo creare applicazioni statiche oppure mantenere attivo un processo sul server per creare pagine in modo dinamico. In entrambi i casi vengono risolti anche alcuni problemi per la SEO, per esempio generando dei file statici per tutti gli indirizzi raggiungibili da un crawler, creando l'istanza della nostra app - o "reidratandola" - da diversi punti di ingresso.

Limiti di un approccio progressivo

Nei casi più ottimali un'applicazione Vue gestisce interamente il processo di visualizzazione delle informazioni, ovvero si occupa della parte di templating.

Quando sviluppiamo un sito che mostra contenuti creati da più autori molto spesso ricorriamo ad un CMS. La maggior parte dei CMS moderni si basa su un pattern ricorrente che si chiama MVC: partendo da dati strutturati in Modelli, rappresento le informazioni con delle Viste vhe vengono generate facendo richieste a dei Controller.

In questo pattern, uno strumento come Vue si colloca nella V, cioè nel templating, nel modo di rappresentare queste informazioni.

In teoria Vue è progettata per essere una libreria progressiva. Questo significa che in un contesto di templating già strutturato (per esempio, con dell'html generato da dei file twig) è possibile "montare" una app Vue in modo minimalista e aggiungere della interattività in modo poco intrusivo.

Sebbene questo sia vero da un punto di vista tecnico, l'esperienza di sviluppo risente parecchio di questo approccio ibrido. Se usiamo Vue in un file twig per qualsiasi cosa che non sia semplice come un dropdown, iniziamo ad avere qualche problema, tra cui:

  • Dobbiamo predisporre una build pipeline in grado di compilare Vue
  • Non sappiamo più con certezza chi è responsabile del templating, e spesso dobbiamo duplicare codice
  • Dobbiamo passare a Vue i dati provenienti da twig, probabilmente strutturando un JSON
  • Includiamo una libreria dimensionata per gestire SPA complesse solo per aggiungere della interattività

In un contesto simile, è chiaro che avere un approccio "progressivo" richiede comunque una riflessione su quale sia la soglia di complessità che richiede di usare qualcosa come Vue.

Se vogliamo imbarcarci totalmente nel mondo delle SPA, possiamo decidere di delegare interamente a Vue il compito di fare templating, chiamando i contenuti via API e gestendo separatamente la navigazione, l'autenticazione, ecc..

Ovviamente, se invece i nostri bisogni sono limitati, potremmo implementare le funzionalità di cui abbiamo bisogno in vanilla js.

Ma probabilmente se abbiamo considerato di usare Vue in parallelo a un CMS, siamo stati in qualche modo attirati dalla semplicità di un approccio dichiarativo, e magari anche da concetti come "località del comportamento" e dall'idea di non dover implementare in continuazione gli stessi pattern basati su ascoltatori e varie funzioni per mostrare, nascondere o modificare il contenuto di una pagina. Allo stesso tempo vogliamo usare la potenza di uno strumento come twig e portarci a casa tutti i benefici del rendering fatto dal nostro CMS.

Approcci alternativi

L'approccio alternativo che mi ispira di più in questo periodo è quello che qualcuno ha definito il "rinascimento del server side rendering".

Alpine js

"I hope you find Alpine to be a breath of fresh air. Silence among noise." - Caleb, creatore di Alpine js.

Questo approccio si basa su due librerie: htmx e Alpine.

In sostanza l'idea è di usare la potenza di un motore di templating come twig, aggiungendo funzionalità e comportamento localmente sugli elementi html.

Htmx si occupa di gestire le richieste a un backend. Usando i tag forniti, un qualsiasi elemento può eseguire richieste AJAX. La differenza rispetto all'approccio classico è che queste richieste restituiscono dei frammenti html, e che quindi vengono restituiti già resi come template.

Alpine invece si occupa di aggiungere interattività in modo dichiarativo. Caleb, il creatore di Alpine, si è ispirato molto a Vue per questo.

Rispetto ad un approccio vanilla, grazie al loro approccio dichiarativo queste due librerie permettono di implementare feature in modo molto rapido, rimanendo molto più leggere e meno intrusive di una libreria come Vue.

Alternativa da esplorare: petit Vue

Esiste un'altra versione di Vue che in teoria permette di ridurre di molto la dimensione di importazione, limitando le funzionalità di Vue. Non ho ancora sperimentato cosa significa in concreto, ma temo che con questo approccio rimarrebbero comunque i problemi di responsabilità del templating e soprattutto di passaggio dei dati. Rimane comunque in #TODO.