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

Questo è il primo post sul blog di ingegneria di web.dev. Nei prossimi mesi, ci auguriamo di condividere informazioni strategiche derivanti dal nostro lavoro, quindi non perderti i post con il tag del blog di ingegneria. Qui tratteremo il processo di creazione 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 più esperti potrebbero aver capito che la nostra pagina Misura è solo un'interfaccia per Lighthouse, disponibile anche in DevTools di Chrome. L'accesso a web.dev ti consente di eseguire controlli regolari di Lighthouse sul tuo sito per vedere come cambia il punteggio nel tempo. Riguardo la pagina Misura un po' più tardi, dato che riteniamo che sia piuttosto speciale. 🎊

Introduzione

Essenzialmente, web.dev è un sito statico generato a partire da una raccolta di file Markdown. Abbiamo scelto di utilizzare Eleventy perché è uno strumento raffinato ed estensibile che semplifica la conversione di Markdown in HTML.

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

Una volta completato il processo di compilazione, che prevede la generazione di HTML statico e il raggruppamento di JavaScript con Rollup, web.dev può essere ospitato su un semplice server statico per il test. Il sito è quasi completamente statico, ma abbiamo alcune esigenze speciali che beneficiano ancora di un server Node.js personalizzato. tra cui i reindirizzamenti per i domini non validi, nonché il codice per analizzare la lingua preferita dell'utente per un'imminente funzionalità di internazionalizzazione.

Generazione statica

Ogni pagina su web.dev è scritta in Markdown. Tutte le pagine includono l'articolo principale, che descrive i metadati relativi a ogni post. Questi metadati vengono importati nel layout di ogni pagina, creando intestazioni, tag e così via. 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...

Questo primo modulo ci permette di definire proprietà arbitrarie come autori, data di pubblicazione e tag. Eleventy espone comodamente la parte frontale come dati in quasi tutti i plug-in, modelli o altri contesti in cui vorremmo svolgere un'azione intelligente. L'oggetto dati contiene anche ciò che Eleventy descrive come la cascade di dati, ovvero una varietà di dati estratti da ogni singola pagina, dal layout utilizzato dalla pagina e dai dati trovati nella struttura gerarchica delle cartelle.

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

Raccolte

Eleventy offre un modo programmatico per creare raccolte arbitrarie di contenuti. In questo modo possiamo creare il supporto per l'impaginazione e generare pagine virtuali (pagine che non hanno un file Markdown corrispondente su disco) per gli autori dei post. Ad esempio, costruiamo le pagine dei nostri autori utilizzando un modello contenente un'espressione per il relativo permalink (in modo che il modello venga sottoposto nuovamente a rendering per ogni autore) e una raccolta di supporto.

Questo si traduce, ad esempio, in una pagina semplice contenente tutti i post di Addy.

Limitazioni

In questo momento non possiamo agganciarci facilmente al processo di creazione di Eleventy perché è dichiarativo, piuttosto che imperativo: sei tu a descrivere ciò che vuoi, piuttosto che come lo vuoi. È difficile eseguire Eleventy come parte di uno strumento di creazione più grande, in quanto può essere richiamato solo tramite l'interfaccia a riga di comando.

Modelli

web.dev utilizza il sistema di modelli Nunjucks originariamente sviluppato da Mozilla. Nunjucks ha le caratteristiche tipiche dei modelli, come loop e condizionali, ma consente anche di definire shortcode che generano ulteriore codice HTML o richiamano altre logiche.

Come gran parte dei team che creavano siti con contenuti statici, abbiamo iniziato con piccoli progressi e nel corso del tempo abbiamo aggiunto codici brevi, circa una ventina. La maggior parte di questi genera solo ulteriore HTML (compresi i nostri componenti web personalizzati). Esempio:

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

L'URL avrà il seguente aspetto:

In realtà, si sta creando HTML che ha il seguente aspetto:

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

Sebbene non rientri nell'ambito di questo post, web.dev utilizza anche gli shortcode come tipo di linguaggio di metaprogrammazione. Gli Short accettano argomenti e uno di essi è il contenuto contenuto. Non è necessario che gli shortcode restituiscano dati, quindi possono essere utilizzati per creare stato o attivare altri comportamenti. 🤔💭

Definisci i tuoi contenuti

Come accennato prima, web.dev è un sito statico, pertanto può essere pubblicato e utilizzato senza JavaScript e da browser meno recenti che non supportano type="module" o il nostro altro codice moderno. Questa è una parte estremamente importante del nostro approccio per rendere web.dev accessibile a tutti.

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

  1. Codice di bootstrap, che include il codice per lo stato globale, l'analisi e il routing SPA
  2. Codice e CSS per i 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 listener globale che ascolti i clic sugli elementi <a href="..."> locali. Il modello SPA ci consente di mantenere lo stato globale della sessione corrente dell'utente, altrimenti ogni nuovo caricamento pagina comporterebbe chiamate a Firebase per accedere allo stato di accesso dell'utente.

Specifica inoltre un paio di entry point diversi nel nostro sito in base all'URL raggiunto e carichiamo quello corretto utilizzando il formato import() dinamico. Ciò riduce il numero di byte necessari agli utenti prima che il sito venga migliorato con il codice.

Componenti web

I componenti web sono elementi personalizzati che incapsulano le funzionalità di runtime fornite 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 quando il codice HTML di un sito viene aggiornato, indicando correttamente a tutti gli elementi quando questi vengono allegati o scollegati dalla pagina. Inoltre, i browser antiquati ignorano del tutto i componenti web ed eseguono il rendering di ciò che rimane nel DOM.

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

Sebbene web.dev utilizzi componenti web su molte pagine, da nessuna parte è necessario trovare la pagina Misura. Due elementi forniscono la maggior parte delle funzionalità disponibili in questa pagina:

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

Questi elementi creano ulteriori elementi che forniscono maggiori funzionalità. È importante sottolineare che questi elementi sono solo parte del nostro codice sorgente Markdown standard e il nostro team addetto ai contenuti può aggiungere funzionalità estese a qualsiasi pagina, non solo al nodo Misura.

I nostri componenti web utilizzano più comunemente il modello 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 quindi esegue il rendering di un elemento visivo, che a sua volta esegue il rendering di nodi DOM effettivi con stili o altre funzionalità integrate.

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

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

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

Parliamone

Il team di tecnici di web.dev (Rob, Ewa, Michael e Sam) seguirà a breve ulteriori approfondimenti tecnici.

Speriamo che le nostre esperienze ti abbiano dato qualche idea per i tuoi progetti. Contattaci su Twitter se hai domande o richieste di argomenti per questo blog!