Introduzione
Febbraio 2023 un mese in un anno di abbondanza sia nel mondo reale che nel mondo digitale, un anno che è appena iniziato. Notizie spaventose continuano a colpire tutti noi, dalla guerra in Ucraina al terremoto in Turchia e Siria, in un periodo in cui l’umanità stava ancora riprendendosi dal virus epidemico COVID-19. Un età di alta connessione tra individui in cui i pensieri non sono mai stati condivisi con tata volontà è facilità attraverso Internet.
Nel corso del tempo la crescita in numero di linguaggi di programmazione e di framework hanno portato gli sviluppatori alla pazzia. Sulle piattaforme social come Twitter e Reddit si tengono continuamente dibattiti apparentemente critici e costruttivi. Basterà solo continuare a scorrere diverse pagine più in fondo che si potranno notare le vere motivazioni. Le parole diventano più dure, le frasi più crudeli e i paragrafi più lunghi. È qui che i dibattiti si trasformano in battaglie e ogni parte suffraga il proprio punto di vista per un unico fine, annichilare l’opposizione. Queste battaglie sono definite battaglia-dei-linguaggi o battaglia-dei-framework.
Anche io combatto le mie battaglie, e ho portato per voi un semplice progetto per divulgare un paradigma di programmazione controverso e impopolare. Mi riferisco alla programmazione funzionale il cui simbolo è il lambda (ƛ) e il linguaggio più moderno è Clojure.
Quali strumenti utilizzeremo?
Uno dei linguaggi più utilizzati per la programmazione web è senza dubbio JavaScript e gli accoliti HTML e CSS.
Poco tempo fa è nato Clojure un nuovo linguaggio, un dialetto del appezzato e altrettanto odiato LISP. Esso ne ha ereditato l’eleganza e le funzionalità, il tutto adattato con comodità aggiuntive alle esigenze moderne. Un linguaggio ospite della JVM dove anche qui ne ha ereditato i pregi e i difetti.
Con l’aumento in popolarità di JavaScript si è sviluppato attorno una community numerosa che ha contribuito a espandere gli strumenti ben oltre le richieste. Cosi Clojure sarebbe andato in ricerca di una nuova piattaforma simbionte. Grazie al ricco ecosistema di JavaScript combinato alle ottimizzazioni fornite dal compilatore Google Closure è nato uno dei linguaggi più potenti che il web abbia mai visto: ClojureScript.
Senza l’HTML non esisterebbe il web come lo conosciamo oggi, un linguaggio di markup con la sintassi XML. Purtroppo questa sintassi non a tutti piacque, e cosi sarebbe nata una nuova libreria per ClojureScript di nome Hiccup con l’obiettivo di tradurre la sintassi XML in una più adatta per i sviluppatori in Clojure. E se in HTML scriviamo <div>...</div>
, visivamente inappagate; nonostante lo sforzo degli editor a venire in soccorso, con Hiccup scriveremo [:div "..."]
, un modo più chiaro e semplice, un modo alla Clojure… Già… Possiamo distinguere una porzione della sintassi di Clojure: []
che di solito rappresenta un contenitore, :div
una keyword, e ""
una stringa.
Gli utenti quando surfano il web si aspettano un certo piacere visivo che può essere soddisfatto con un l’aggiunta del CSS. Però sono tempi moderni e sono rimasti in pochi gli sviluppatori puristi che programmano in vanilla. E come biasimare la maggioranza, i framework assistono lo sviluppatore a produrre a una velocità singolare. Per questo ho scelto di usare TailwindCSS che porta classi già implementate che vengono utilizzate direttamente nel codice HTML. In più utilizzeremo anche DaisyUI, una libreria di componenti.
Un altro framework che utilizzeremo in questo progetto è Reagent un interfaccia in Clojure per React. E queste è tutto ciò che c’è da dire sulla sua esistenza.
shadow-cljs, che ci approvvigiona con tutti gli utili per compilare il codice ClojureScript.
NPM, uno strumento da linea di comando che useremo per installare i pacchetti su cui dipenderà il nostro progetto.
Questi strumenti sono nuovi e carini, ma non eccitatevi troppo, ancora avrete da vedere l’attrazione principale, la sintassi all’hamburger di LISP.
Prima d’inziare installa i requisiti
Lista breve dei requisiti.
Durante questo articolo utilizziamo la shell di Linux.
Per installare i pacchetti su MacOS usa brew. Per Windows esiste un modo attraverso VSCode per avere la shell, più informazioni qui. Quando installi i programmi attraverso il package manager i comandi potrebbero variare in base alla distribuzione, la mia è Debian. È per questo che è meglio andare sul sito del programma e installarlo secondo le istruzioni ufficiali.
Installa Java, la versione open source: openjdk.
|
|
Prima d’installare Clojure, assicurati prima che le dipendenze bash
, curl
, rlwrap
siano installate.
|
|
/bin/bash
/usr/bin/curl
/usr/local/bin/rlwrap
Altrimenti installli.
|
|
Installa Clojure.
|
|
Installa NodeJS.
|
|
Ti consiglio d’installare VSCode, ma utilizza il binario senza telemetria di VSCodium.
Inizializzare il progetto
Inizializziamo il progetto per avere un ambiente di sviluppo adeguato.
Installa e configura l’aiutante di Clojure per VSCode: Calva, oppure guarda questa lista, potresti trovare un aiutante per il tuo editor preferito.
Inizializza lo scheletro del progetto con shadow-cljs.
|
|
Aggiungi gli script NPM
In package.json
.
|
|
- Useremo questi script durante lo sviluppo.
Installa le dipendenze
|
|
Configura TailwindCSS
In tailwind.config.js
.
|
|
- Riga 5, aggiunto il font Roboto.
- Riga 10, aggiunto il plugin DaisyUI.
In resources/css/tailwind.css
.
|
|
- Aggiunte le classi richieste da TailwindCSS che PostCSS risolverà durante la compilazione attraverso un script che abbiamo definito in
package.json
.
Configura PostCSS
In postcss.config.js
.
|
|
Aggiungi le pagine principali
In resources/index.html
.
|
|
In src/main/landing_page/app.cljs
.
|
|
- Riga 2, aggiunta la libreria reagent.dom.
- Riga 4, definita la funzione app che conterrà più avanti tutti i componenti della pagina web.
- Riga 7, definita la funzione start che monta i componenti nella DOM attraverso rd/render che accetta due argomenti.
- Il primo è [app], la chiamata alla funzione app nella sintassi di Reagent. Può essere anche chiamata nella sintassi di Clojure
(rd/render (app) ...)
, però per motivi di efficienza si usa la sintassi di reagent(rd/render [app] ...)
. Più informazioni nella documentazione ufficiale. - Il secondo è
(.getElementById js/document "app")
che prende l’id app nel fileindex.html
.
- Il primo è [app], la chiamata alla funzione app nella sintassi di Reagent. Può essere anche chiamata nella sintassi di Clojure
- Riga 11, definita la funzione main che è chiamata da shadow-cljs per eseguire l’ambiente di sviluppo.
Fai partire la modalità sviluppo
|
|
Vai all’indirizzo http://localhost:8080 e verifica che venga visualizzata la scritta Hello World!.
Sviluppa il sito
Ora che il progetto contiene tutte le parti necessarie strutturiamo la pagina in componenti.
- Hero
Contiene un titolo, una descrizione e un pulsante per scorrere più in basso. È la prima cosa che l’utente vedrà quando si collegherà al sito e dovrà occupare tutto lo spazio della pagina.
- Terminal
Contiene la schermata di un terminale con una breve descrizione su come scaricare questo progetto.
- Footer
Compone la parte finale della pagina. Verranno visualizzati il logo, i social e la licenza.
- Notice
Contiene una notifica pop-up che informerà l’utente sui cookies utilizzati dal sito. Potrà essere chiusa attraverso un pulsante.
- App
app.cljs
, è il file dove tutti i componenti vengono chiamati.
Crea il componente hero
In src/main/landing_page/components/hero.cljs
.
|
|
- Riga 1, definisce il namespace
(ns landing-page.components.hero)
. - Riga 3, definisce la funzione main, senza argomenti.
Crea il componente terminale
In src/main/landing_page/components/terminal.cljs
.
|
|
Crea il componente footer
In src/main/landing_page/components/footer.cljs
.
|
|
Crea il componente notice
In src/main/landing_page/components/notice.cljs
.
|
|
- Riga 2,
(:require [reagent.core :as r])
serve per importare la libreria reagent.core. - Riga 4,
(def state (r/atom {:hidden false}))
definisce un atomo di nome state. È una variabile che registra lo stato del componente per determinare se il componente è visibile o nascosto. - Riga 8,
{:class (str "toast toast-center sm:toast-start z-10 " (when (:hidden @state) "hidden"))}
, aggiunge la classe hidden se lo stato della variabile state è {:hidden true}. - Riga 28,
:on-click #(swap! state assoc :hidden true)
, quando si preme il pulsante cambia lo stato di state in {:hidden true}.
Chiama i componenti nel file principale
In src/main/landing_page/app.cljs
.
|
|
- Importati tutti i componenti fino a ora definiti.
- Riga 8, in app vengono chiamate le funzioni main di tutti i componenti.
Conclusioni
Il sito web è finto. Crea una build per la versione distibuibile.
|
|
Il sito si trova in target/dist
. Può essere fatto il deploy su un qualsiasi web server.