blog di ingegneria web.dev n. 1: Come creiamo il sito e utilizziamo i componenti web

Questo è il primo post del blog di engineering di web.dev. Nei prossimi mesi, ci auguriamo di condividere informazioni utili derivanti dal nostro lavoro, quindi tieni d'occhio i post con il tag del blog di ingegneria. Qui illustreremo la procedura di compilazione del nostro sito statico e la (facoltativa) JavaScript alla base dei nostri componenti web.

web.dev fornisce contenuti sulla creazione di esperienze web moderne e ti consente di misurare il rendimento del tuo sito. Gli utenti esperti potrebbero aver notato che la nostra pagina Misura è solo un'interfaccia per Lighthouse, che è disponibile anche in DevTools di Chrome. Se accedi a web.dev, puoi eseguire regolarmente controlli Lighthouse sul tuo sito per vedere come cambia il punteggio nel tempo. Tornerò alla pagina Misura un po' più tardi, perché riteniamo che sia piuttosto speciale. 🎊

Introduzione

Fondamentalmente, web.dev è un sito statico generato da una raccolta di file Markdown. Abbiamo scelto di utilizzare Eleventy perché è uno strumento raffinato ed estensibile che consente di trasformare facilmente Markdown in HTML.

Utilizziamo anche bundle JavaScript moderni che pubblichiamo solo nei browser che supportano type="module", tra cui async e await. Utilizziamo anche funzionalità supportate dai browser permanenti, ma non da una minoranza di versioni precedenti. Poiché siamo un sito statico, JavaScript non è necessario per leggere i nostri contenuti.

Una volta completata la procedura di compilazione, che prevede la generazione di HTML statico e il raggruppamento del codice JavaScript con Rollup, web.dev può essere ospitato su un semplice server statico per i test. Il sito è quasi completamente statico, ma abbiamo alcune esigenze speciali che possono essere soddisfatte con un server Node.js personalizzato. Sono inclusi i reindirizzamenti per i domini non validi, nonché il codice per analizzare la lingua preferita di un utente per una funzionalità di internazionalizzazione in arrivo.

Generazione di annunci statici

Ogni pagina su web.dev è scritta in Markdown. Tutte le pagine includono premessa, che descrive i metadati di ogni post. Questi metadati vengono importati nel layout di ogni pagina, creando intestazioni, tag e così via. Ecco un esempio:

---
layout: post
title: What is network reliability and how do you measure it?
authors:
  - jeffposnick
date: 2018-11-05
description: |
  The modern web is enjoyed by a wide swath of people…
---

The modern web is enjoyed by a wide swath of [people](https://www.youtube.com/watch?v=dQw4w9WgXcQ), using a range of different devices and types of network connections.

Your creations can reach users all across the world...

Questa parte iniziale ci consente di definire proprietà arbitrarie come autori, data di pubblicazione e tag. Eleventy espone comodamente la premessa come dati in quasi tutti i plug-in, modelli o altri contesti in cui vogliamo fare qualcosa di intelligente. L'oggetto dati contiene anche ciò che Eleventy descrive come cascata di dati: una serie di dati estratti da ogni singola pagina, dal layout utilizzato dalla pagina e dai dati trovati nella struttura gerarchica delle cartelle.

Ogni layout unico descrive un tipo diverso di contenuti e può ereditare da altri layout. Su web.dev utilizziamo questa funzionalità per inquadrare correttamente diversi tipi di contenuti (come post e codelab) pur condividendo un layout HTML di primo livello.

Raccolte

Eleventy fornisce un modo programmatico per creare raccolte arbitrarie di contenuti. In questo modo, abbiamo potuto creare il supporto della paginazione e generare pagine virtuali (pagine che non hanno un file Markdown corrispondente sul disco) per gli autori dei post. Ad esempio, costruiamo le pagine degli autori utilizzando un modello contenente un'espressione per il relativo permalink (in modo che il modello venga visualizzato di nuovo per ogni autore) e una raccolta di supporto.

Ad esempio, viene visualizzata una semplice pagina contenente tutti i post di Addy.

Limitazioni

Al momento non possiamo collegarci facilmente al processo di compilazione di Eleventy perché è declarativo anziché imperativo: descrivi cosa vuoi, non come lo vuoi. È difficile eseguire Eleventy all'interno di uno strumento di compilazione più grande, in quanto può essere richiamato solo tramite la sua interfaccia a riga di comando.

Modelli

web.dev utilizza il sistema di creazione di modelli Nunjucks originariamente sviluppato da Mozilla. Nunjucks offre le funzionalità di creazione di modelli tipiche, come i loop e i controlli condizionali, ma ci consente anche di definire shortcode che generano ulteriore codice HTML o invocano altra logica.

Come la maggior parte dei team che creano siti di contenuti statici, abbiamo iniziato in piccolo e abbiamo aggiunto gli shortcode nel tempo, fino ad arrivare a circa 20. La maggior parte di questi genera solo altro codice HTML (inclusi i nostri componenti web personalizzati). Ecco un esempio:

{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}

L'aspetto sarà simile al seguente:

In realtà, però, sta creando codice HTML simile al seguente:

<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>

Anche se non rientra nell'ambito di questo post, web.dev utilizza gli shortcode come tipo di linguaggio di metaprogrammazione. I shortcode accettano argomenti, uno dei quali è costituito dai contenuti contenuti. Non è necessario che gli shortcode restituiscano nulla, quindi possono essere utilizzati per creare stati o attivare altri comportamenti. 🤔💭

Definisci i tuoi contenuti

Come accennato in precedenza, poiché web.dev è un sito statico, può essere pubblicato e utilizzato senza JavaScript e da browser meno recenti che non supportano type="module" o il nostro altro codice moderno. Si tratta di un aspetto incredibilmente importante del nostro approccio per rendere web.dev accessibile a tutti.

Tuttavia, il nostro codice per i browser moderni è composto da due parti principali:

  1. Codice di bootstrap, che include il codice per lo stato globale, Analytics e il routing SPA
  2. Codice e CSS per componenti web che migliorano progressivamente il sito

Il codice di bootstrap è abbastanza semplice: web.dev può caricare nuove pagine come applicazione a pagina singola (SPA), quindi installiamo un ascoltatore globale che rileva i clic sugli elementi <a href="..."> locali. Il modello SPA ci aiuta a mantenere lo stato globale della sessione corrente dell'utente, altrimenti ogni nuovo caricamento di pagina attiverebbe chiamate a Firebase per accedere allo stato di accesso di un utente.

Specifichiamo anche un paio di punti di contatto diversi nel nostro sito in base all'URL che hai visitato e carichiamo quello corretto utilizzando import() dinamico. In questo modo, riduciamo il numero di byte di cui hanno bisogno i nostri utenti prima che il sito venga migliorato con il codice.

Componenti web

I componenti web sono elementi personalizzati che incapsulano la funzionalità di runtime fornita in JavaScript e sono identificati da nomi personalizzati come <web-codelab>. Il design si presta bene a siti in gran parte statici come web.dev: il browser gestisce il ciclo di vita di un elemento man mano che l'HTML di un sito viene aggiornato, informando correttamente gli elementi quando vengono collegati o scollegati dalla pagina. I browser obsoleti ignorano completamente i componenti web e visualizzano ciò che rimane nel DOM.

Ogni componente web è una classe con metodi tra cui connectedCallback(), disconnectedCallback() e attributeChangedCallback(). Gli elementi personalizzati di web.dev ereditano per lo più da LitElement, che fornisce una base semplice per componenti complessi.

Sebbene web.dev utilizzi i componenti web in molte pagine, non è necessario più che altro nella pagina Misura. La maggior parte delle funzionalità visualizzate in questa pagina è fornita da due elementi:

<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>

Questi elementi creano altri elementi che forniscono più funzionalità. È importante sottolineare che questi elementi fanno parte del nostro normale codice sorgente Markdown e il nostro team di contenuti può aggiungere funzionalità estese a qualsiasi pagina, non solo al nodo Misura.

I nostri componenti web utilizzano più comunemente il modello del componente contenitore, reso popolare da React, anche se questo modello ora è un po' superato. Ogni elemento -container si connette al nostro stato globale (fornito da unistore) e poi esegue il rendering di un elemento visivo, che a sua volta esegue il rendering di nodi DOM effettivi con stili o altre funzionalità integrate.

Un diagramma che mostra la relazione tra lo stato globale e gli elementi HTML che lo utilizzano.
Stato globale e componente web

I nostri componenti web più complessi esistono per visualizzare azioni e stato globali. Ad esempio, web.dev ti consente di eseguire un audit del tuo sito preferito e poi di uscire dalla pagina Misura. Se torni, vedrai che l'attività è ancora in corso.

I nostri componenti semplici migliorano semplicemente i contenuti altrimenti statici o creano visualizzazioni straordinarie (ad esempio, ogni grafico a linee è un proprio <web-sparkline-chart>), che non ha alcuna relazione con lo stato globale.

Parliamone

Il team di ingegneria di web.dev (Rob, Ewa, Michael e Sam) pubblicherà a breve altri approfondimenti tecnici.

Ci auguriamo che le informazioni su come lavoriamo ti abbiano dato qualche idea per i tuoi progetti. Contattaci su Twitter se hai domande o richieste di argomenti per questo blog.