Blog d'ingénierie web.dev n° 1: Comment créer le site et utiliser les composants Web

Il s'agit du premier post du blog technique de web.dev. Au cours des prochains mois, nous espérons partager des insights pratiques issus de notre travail. Tenez donc à l'œil les posts avec la balise de blog technique. Nous allons ici décrire le processus de compilation de notre site statique et les (facultatifs) JavaScript derrière nos composants Web

web.dev fournit des contenus sur la création d'expériences Web modernes et vous permet de mesurer les performances de votre site. Les utilisateurs avertis ont peut-être remarqué que la page "Mesure" n'est qu'une interface de Lighthouse, qui est également disponible dans les outils pour les développeurs de Chrome. En vous connectant à web.dev, vous pouvez effectuer des audits Lighthouse réguliers sur votre site afin de voir comment son score évolue au fil du temps. Je reviendrai sur la page "Mesure" un peu plus tard, car nous pensons qu'elle est assez spéciale. 🎊

Introduction

Web.dev est fondamentalement un site statique généré à partir d'une collection de fichiers Markdown. Nous avons choisi d'utiliser Eleventy, car il s'agit d'un outil soigné et extensible qui permet de convertir facilement du Markdown en HTML.

Nous utilisons également des bundles JavaScript modernes que nous diffusons uniquement aux navigateurs compatibles avec type="module", y compris async et await. Nous utilisons également des fonctionnalités compatibles avec les navigateurs evergreen, mais pas avec une minorité d'anciennes versions. Étant donné que nous utilisons un site statique, JavaScript n'est tout simplement pas nécessaire pour lire notre contenu.

Une fois le processus de compilation terminé (qui implique de générer du code HTML statique et d'empaqueter notre code JavaScript avec Rollup), web.dev peut être hébergé sur un serveur statique simple à des fins de test. Le site est presque entièrement statique, mais nous avons quelques besoins particuliers qui nécessitent un serveur Node.js personnalisé. Il s'agit notamment des redirections pour les domaines non valides, ainsi que du code pour analyser la langue préférée de l'utilisateur pour une fonctionnalité d'internationalisation à venir.

Génération statique

Chaque page de web.dev est écrite en Markdown. Toutes les pages incluent une partie avant, qui décrit les métadonnées de chaque post. Ces métadonnées sont ingérées dans la mise en page de chaque page, créant des titres, des balises, etc. Exemple :

---
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...

Cette partie nous permet de définir des propriétés arbitraires telles que l'auteur ou les auteurs, la date de publication et les tags. Eleventy expose de manière pratique la préface en tant que données dans presque tous les plug-ins, modèles ou autres contextes dans lesquels nous aimerions effectuer une action intelligente. L'objet de données contient également ce qu'Eleventy décrit comme la cascade de données : une variété de données extraites de chaque page, de la mise en page utilisée par la page et des données trouvées dans la structure de dossiers hiérarchique.

Chaque mise en page unique décrit un type de contenu différent et peut hériter d'autres mises en page. Sur web.dev, nous utilisons cette fonctionnalité pour encadrer correctement différents types de contenus (comme les articles et les ateliers de programmation) tout en partageant une seule mise en page HTML de niveau supérieur.

Collections

Eleventy permet de créer de manière programmatique des collections de contenus arbitraires. Cela nous a permis de créer la prise en charge de la pagination et de générer des pages virtuelles (pages qui ne disposent pas d'un fichier Markdown correspondant sur le disque) pour les auteurs de posts. Par exemple, nous construisons nos pages d'auteurs à l'aide d'un modèle contenant une expression pour son lien permanent (afin que le modèle soit à nouveau généré pour chaque auteur) et une collection de sauvegarde.

Vous obtenez ainsi, par exemple, une page simple contenant tous les posts d'Addy.

Limites

Pour le moment, nous ne pouvons pas facilement nous connecter au processus de compilation d'Eleventy, car il est déclaratif plutôt que impératif: vous décrivez ce que vous voulez, et non comment vous le voulez. Il est difficile d'exécuter Eleventy dans le cadre d'un outil de compilation plus important, car il ne peut être appelé que via son interface de ligne de commande.

Modèle

web.dev utilise le système de création de modèles Nunjucks, développé à l'origine par Mozilla. Nunjucks dispose des fonctionnalités de création de modèles typiques, comme les boucles et les conditions, mais permet également de définir des shortcodes qui génèrent du code HTML supplémentaire ou appellent d'autres logiques.

Comme la plupart des équipes qui créent des sites de contenu statique, nous avons commencé par ajouter quelques shortcodes, puis nous en avons ajouté d'autres au fil du temps (environ 20 à ce jour). La plupart d'entre eux ne génèrent que du code HTML supplémentaire (y compris nos composants Web personnalisés). Exemple :

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

Le résultat ressemblera à ceci:

En réalité, il crée du code HTML qui se présente comme suit:

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

Bien que cela ne relève pas du champ d'application de cet article, web.dev utilise également les shortcodes comme type de langage de métaprogrammation. Les shortcodes acceptent des arguments, dont l'un est le contenu inclus. Les codes courts ne sont pas obligés de renvoyer quoi que ce soit. Ils peuvent donc être utilisés pour créer un état ou déclencher un autre comportement. 🤔💭

Script

Comme indiqué précédemment, étant donné que web.dev est un site statique, il peut être diffusé et utilisé sans JavaScript, et par les anciens navigateurs qui ne sont pas compatibles avec type="module" ni avec notre autre code moderne. Il s'agit d'une partie extrêmement importante de notre approche visant à rendre web.dev accessible à tous.

Cependant, notre code pour les navigateurs modernes se compose de deux parties principales:

  1. Code de démarrage, qui comprend le code pour l'état global, Analytics et le routage d'application monopage
  2. Code et CSS pour les composants Web qui améliorent progressivement le site

Le code de démarrage est assez simple: web.dev peut charger de nouvelles pages en tant qu'application monopage (SPA). Nous installons donc un écouteur global qui écoute les clics sur les éléments <a href="..."> locaux. Le modèle SPA nous aide à conserver l'état global de la session en cours de l'utilisateur, car sinon chaque nouvelle page chargée déclencherait des appels à Firebase pour accéder à l'état de connexion de l'utilisateur.

Nous spécifions également plusieurs points d'entrée sur notre site en fonction de l'URL que vous avez consultée, et nous chargeons le bon point d'entrée à l'aide de import() dynamique. Cela réduit le nombre d'octets dont nos utilisateurs ont besoin avant que le site ne soit amélioré avec du code.

Composants Web

Les composants Web sont des éléments personnalisés qui encapsulent les fonctionnalités d'exécution fournies en JavaScript et sont identifiés par des noms personnalisés tels que <web-codelab>. Cette conception convient bien aux sites largement statiques comme web.dev: votre navigateur gère le cycle de vie d'un élément lorsque le code HTML d'un site est mis à jour, informant correctement les éléments lorsqu'ils sont associés ou dissociés de la page. Les navigateurs obsolètes ignorent complètement les composants Web et affichent tout ce qui reste dans le DOM.

Chaque composant Web est une classe avec des méthodes, y compris connectedCallback(), disconnectedCallback() et attributeChangedCallback(). Les éléments personnalisés de web.dev héritent principalement de LitElement, qui fournit une base simple pour les composants complexes.

Bien que web.dev utilise des composants Web sur de nombreuses pages, il n'est nulle part plus nécessaire que sur la page Mesurer. Deux éléments fournissent l'essentiel des fonctionnalités que vous voyez sur cette page:

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

Ces éléments créent d'autres éléments qui offrent plus de fonctionnalités. Il est important de noter que ces éléments ne font qu'une partie de notre code source Markdown standard. Notre équipe de contenu peut ajouter des fonctionnalités étendues à n'importe quelle page, et pas seulement au nœud "Mesure".

Nos composants Web utilisent le plus souvent le modèle de composant conteneur, popularisé par React, bien que ce modèle soit désormais un peu dépassé. Chaque élément -container se connecte à notre état global (fourni par unistore), puis affiche un élément visuel, qui à son tour affiche des nœuds DOM réels dotés de styles ou d'autres fonctionnalités intégrées.

Diagramme illustrant la relation entre l&#39;état global et les éléments HTML qui l&#39;utilisent.
État global et composant Web

Nos composants Web les plus complexes permettent de visualiser les actions et l'état globaux. Par exemple, web.dev vous permet d'auditer votre site préféré, puis de quitter la page "Mesure". Si vous revenez, vous verrez que la tâche est toujours en cours.

Nos composants simples ne servent qu'à améliorer un contenu statique ou à créer des visualisations étonnantes (par exemple, chaque graphique linéaire est son propre <web-sparkline-chart>), qui n'ont aucun lien avec l'état global.

Parlons-en ensemble

L'équipe d'ingénieurs web.dev (Rob, Ewa, Michael et Sam) vous proposera bientôt d'autres analyses techniques.

Nous espérons que vous avez trouvé des idées pour vos propres projets. N'hésitez pas à nous contacter sur Twitter si vous avez des questions ou des suggestions de sujets pour ce blog.