Come sviluppare questo sito: Next.js, Fermo, Gatsby, Middleman. Appunti su cosa imparo.

/ Geek & Business

Ho deciso di aprire un blog; i motivi li spiego nella pagina Perchè questo sito

Dopodiché c'è da svilupparlo e le opzioni davanti a me sono numerose. Una chiacchierata con l'amico Cecio fu galeotta: parlavamo dello stato dell'arte del mondo CMS, HeadlessCMS in particolare e delle scelte ottimali per la realizzazione del suo sito personale. E se il sito fosse il mio, quali tecnologie sceglierei? Quali compromessi? E nel cercare le risposte, è nata anche la voglia di provarci!

Conosco l'ambito web molto bene, è il mio lavoro. Ma scegliere in modo pragmatico, mettendo sul piatto il tempo da dedicare al progetto, una visione a lungo termine e le competenze personali a disposizione (perché te lo devi fare da te e non hai un team di esperti allo sviluppo su cui contare), non è affatto banale.

Per inziare ho definito alcuni assunti:

  • Ho due tipi di contenuti: pubblici e privati e voglio che finiscano su due canali differenti: i pubblici su un un blog online; i privati (preferibilmente in un formato markdown), in locale e/o su un git privato; comunque in uno spazio cloud accessibile in futuro per i miei familiari.

  • Per scrivere e organizzare entrambe le tipologie di contenuto, uso DatoCMS. È un prodotto che ho contribuito a far nascere e funziona maledettamente bene.

  • Per sviluppare il frontend, ho deciso di divertirmi ad imparare qualcosa che conosco ma di cui ho poca pratica diretta, perché il mio lavoro in Cantiere Creativo è ormai più strategico/organizzativo che operativo. Col codice sono rimasto troppo indietro, la lacuna è da colmare!

Quale generatore usare?

Se il CMS è chiaro, l'SSG ha richiesto un po' di riflessioni in più.

Conosco approfonditamente Middleman che ho uso dal 2014 per fare progetti di dimensioni grosse, come il sito del Ministero per l'Innovazione Digitale, che ridotte come Acacia.

Hero di Middleman 4

Middleman è potente e fatto bene e ha una serie di caratteristiche che apprezzo particolarmente:

  • È scritto in ruby, linguaggio con cui ho confidenza, e posso usare il vasto ecosistema di gemme

  • Permette di usare Slim, un markup che adoro.

  • Ha un sistema di partials e layout che permettono di costruire dei componenti riutilizzabili.

  • Posso inizializzare un nuovo progetto e averlo online su Netlify in circa 30 secondi.

  • Offre un sistema di proxy per gestire i template in modo separato ed elegante.

  • Il server locale costruisce la singola pagina al volo al momento della richiesta. La connessione live al CMS restituisce i contenuti aggiornati. Infine il sistema livereload ricarica la pagina automaticamente ad ogni salvataggio di contenuto, html o css. Lo sviluppo, una festa.

Di contro ha un grosso problema di performance: la build finale è lenta e con l'aumentare dei contenuti non può che andare a peggiorare. Un sito di medie dimensioni può richiedere circa 6 minuti per il deploy, ma non è raro vedere build da oltre 20 minuti. Senza un sistema di preview, per gli editor diventa una situazione davvero inaccettabile, è solo una questione di tempo.

Le alternative

Ho scartato il trendissimo Gatsby con cui non ho mai avuto a che fare: onestamente ho sentito troppi moccoli intorno a questo framework per cui non mi azzarderei. Gatsby è di fatto un SSG, anche se usa React, i problemi di performance in fase di deploy non migliorano e se provi ad uscire dal seminato, avrai sicuramente problemi.

Hugo è potente in termini di performance, ma lo sviluppo è una pena quando sei abituato alle caratteristiche di Middleman. Jeckyll, non lo prendo proprio in considerazione, sembra preistoria.

Ho quindi due alternative, e in qualche modo le userò entrambe: Next.js per il blog e Fermo per i contenuti privati.

Fermo

È un framework OpenSource scritto in Elixir concepito da Joe Yates, amico e collega di una vita, nonché CTO in Cantiere Creativo. Stanchi di cercare di migliorare le performance di Middleman e dopo aver creato un CMS per siti statici, creare un generatore di siti statici è venuto quasi naturale. Elixir sta diventando quasi uno standard in Cantiere, proprio per le incredibili performance che garantisce. Fermo è stato scritto "copiando" tutto ciò che di buono c'è in Middleman, ma ottimizzando alcune lacune.

Fermo is faster than the fastest Static Site Generator you can think of when building big, complex websites. Yes, even *that* one.

Fermo è ancora in una release alpha, anche se lo abbiamo usato già in numerosi progetti in produzione. Sfrutta i multiprocessori per generare le pagine, permette di fare query in GraphQL, sfruttare le magie delle immagini responsive fornite da DatoCMS, permette di avere un sistema di preview. Elixir non è diffuso come Ruby, ma ha comunque una vasta gamma di librerie (chiamate mix) per cui abbiamo Slime (corrispettivo di Slim), Sass e tutto ciò che serve.

Userò Fermo per costruire i file Markdown in locale. Capisco che possa sembrare insensato avere due applicazioni separate per fare cose simili. Ma tanto simili non sono: i contenuti hanno accesso differente, l'output è completamente differente e, cosa più importante, voglio divertirmi ad usarlo 😉

Next.js

È in hype totale in questo ultimo anno e non c'è da stupirsi. Fatto bene, con idee innovative alla base. Con Next.js posso sfruttare il sistema isomorfo per avere sia contenuti statici che dinamici, serviti da un potente sistema di cache. Con Vercel, l'esperienza di deploy è ormai pari a quella di Netlify. Inoltre DatoCMS e Next.js sono buoni amici, il supporto è totale in entrambi i sensi.

Di contro:

  • 😢 Non ho esperienza con React, se non teorica per osmosi in ufficio

  • 😢 Non posso usare Slim

  • 😢 Se consumo tanto tempo ad imparare Next/React, non posso mettermi a fare anche il css come piace a me, usando BEMO come base e poi scritto di cesello, ad-hoc con Bem. Devo usare un framework tipo Bootstrap, Tailwind ecc.

Al contempo sono contento perché:

  • Posso sperimentare sulla mia pelle e comprendere a fondo qualcosa che, di fatto, vendo e consiglio tutti i giorni. È sempre bello imparare qualcosa di nuovo.

  • Alcuni aspetti dei componenti React mi piacciono un sacco e le possibilità sono notevoli lato frontend.

  • Posso partire da uno starter kit di Dato e di fatto questo sito è andato online in poco più di 30 secondi.

Dopodiché, c'è la personalizzazione, e qui viene il bello!

WIP: Cosa sto imparando?

Prenderò qui appunti delle varie cose che imparo.

CSS

Antecedenti: ho odiato Bootrstrap, molto, per molto tempo, a favore del Bem che salvò i frontendisti in Cantiere Creativo: css mantenibili negli anni, svincolo da un unico sviluppatore, non più migliaia di righe di css ma singoli blocchi indipendenti, controllo totale dello stile. ✌️Vittoria indiscussa su tutti i fronti.

Ho dovuto usare Bootstrap per il sito del Midt, e nei mesi ho apprezzato numerosi aspetti. I sistemi utiltiy-first ti obbligano ad usare una quantità insopportabile di classi per ogni tag senza contare il fatto che, in caso di personalizzazioni, devi necessariamente andare di override e !important, il male assoluto.

Poiché ho imparato Bootstrap usandolo sul campo, sarebbe stata per me la scelta più ovvia; ma non può andare sempre tutto liscio: lo starter kit del blog utilizza Tailwind, mai visto prima. Ho speso un po' di tempo per leggere la documentazione, ho fatto qualche prova e devo dire che mi ha convinto: sembra più snello e più centrato nel suo obiettivo di essere utility first. Inoltre offre una discreta libreria di componenti, già pronti anche in React. Dopo le prime personalizzazioni, non l'ho odiato — il che non è poco! Vamos 🦾

GraphQL

Capisco che la query debba essere fatta dentro ogni pagina, mentre i componenti non possono avere query ma solo ricevere i dati. dalla pagina. Qui iniziano i primi dubbi:

  • Come gestisco il passaggio dei dati in sotto componenti? Alla fine non si perde di chiarezza?

  • C'è un modo per evitare di ripetere query identiche in ogni pagina?

Una via possono essere i fragment, ovvero porzioni di query che possono essere richiamate dentro la query di una pagina. Ma non era questo che mi interessava. Ho capito che posso creare dentro la directory lib (o utils, a preferenza) dei file/funzioni a cui delegare sia la query che la creazione dei dati necessari a creare un componente.

Ho usato questo sistema per generare l'elenco di categorie in cui è presente almeno un articolo. Questo componente è presente in diverse pagine, e avrei dovuto fare la query in ognuna di esse.

Quindi ho creato il file lib/activeCategories.js

import { request } from './datocms';

const query = `
  {
    allCategories {
      description
      id
      name
      slug
    }
    allPosts(filter: {isPublic: { eq: true }}) {
      category{
        id
      }
    }
  }
`;

export default async() => {
  const result = await request({ query })
  const { allPosts, allCategories } = result

  const categories = allCategories.map(cat => {
    const matching = allPosts.filter(p => p.category.id == cat.id)
    return matching.length > 0 ? cat : null
  })
  const catsWithPosts = categories.filter(c => !!c)
  
  return catsWithPosts
}

Là dove lo voglio usare basta richiamare

const categories = await activeCategories()

Per poi renderizzarlo così

<ul className="flex flex-row flex-wrap my-8">
     {categories.map(cat =>
       <li className="mb-3 mr-3 rounded-md bg-green-500 text-white flex items-center justify-center md:text-lg lg:text-2xl font-bold rounded-t-xl p-2 px-4">
         <Link as={`/categories/${cat.slug}`} href="/categories/[slug]">
           <a className="hover:underline">{cat.name}</a>
         </Link>
       </li>
     )}
   </ul>

Il tutto per ottenere questo

Elenco di categorie in cui è presente almeno un post pubblico

Errori babbani:

  • Non commentare le righe nelle query. Perderai ore a cercare il bug nella query quando l'errore è solo quel dannato commento. 😤

React

È importante capire la differenza tra funzioni "normali" e le funzioni asicnrone. Ho un po' sottovalutato questo aspetto. Anche se può sembrare datato, un articolo interessante di Bob Nystorm è "What color is your function" può aiutare.

Iframes

Come embeddare iframes in modo corretto e con un occhio a sicurezza e performance. Leggi chi ci è passato prima di me!

Next


Geek & Business

Ho inziato con un Commodore64 quando avevo nove anni. Da lì la passione per i computer e la tecnologia in generale non è mai tramontata. Ho una conoscenza trasversale di tanti aspetti del mondo sowtare per il web. Nei tanti anni di lavoro ho sviluppato applicativi web soprattutto in Rails, visual design, UX, un po' di 3d; ma la cosa su cui mi sento più confortevole è sicuramente lato frontend. Ho fondato un'azienda di sviluppo web che si chaima Cantiere Creativo in cui oggi seguo la produzione, la cultura aziendale, la metodologia, la strategia.

Tutti gli articoli

Altre amenità

Ode a Sting e al "drumming genius" Vinnie Colaiuta

"Saint Augustine in Hell" di Sting è un pezzo musicale di livello enorme. La band è fotonica e Vinnie Colaiuta è pressoché grandioso Ho avuto la fortuna di partecipare ad un seminario con lui, dove ho potuto apprendere un piccolo segreto del suo genio su quel pezzo.

/ Musica / Drum

Unconventional wedding

Cosa significa "matrimonio" e cosa si insidia nelle parole "per tutta la vita, nel bene e nel male"? Il mio primo matrimonio da cerimoniere, qualche parola di augurio per i miei amici sposi.