To pierwszy post na blogu inżynierów web.dev. W najbliższych miesiącach chcemy udostępniać przydatne informacje o naszych działaniach. Wypatruj więc posty z tagiem Blog inżynierski. W tym artykule omówimy proces kompilacji witryny statycznej i (opcjonalnie) kod JavaScript, który obsługuje nasze komponenty internetowe;
web.dev zawiera treści dotyczące tworzenia nowoczesnych stron internetowych i umożliwia pomiar wydajności witryny. Doświadczeni użytkownicy mogą zauważyć, że nasze narzędzie Measure to tylko interfejs Lighthouse, który jest też dostępny w Narzędziach deweloperskich w Chrome. Po zalogowaniu się na stronie web.dev możesz regularnie przeprowadzać audyty Lighthouse w swojej witrynie, aby sprawdzać, jak zmienia się jej wynik w czasie. Wrócę na stronę Pomiar później, ponieważ jest ona naszym zdaniem wyjątkowa. 🎊
Wprowadzenie
Web.dev to witryna statyczna, która jest generowana na podstawie kolekcji plików Markdown. Używamy Eleventy, ponieważ jest to dopracowane, rozszerzalne narzędzie, które ułatwia przekształcanie Markdowna w HTML.
Używamy też nowoczesnych pakietów JavaScript, które wyświetlamy tylko w przeglądarkach obsługujących type="module"
, w tym async
i await
.
Z przyjemnością korzystamy też z funkcji obsługiwanych przez przeglądarki evergreen, ale nie przez starsze wersje.
Ponieważ nasza witryna jest statyczna, do odczytania jej treści nie jest wymagany JavaScript.
Po zakończeniu procesu kompilacji, który obejmuje wygenerowanie statycznego kodu HTML i połączenie naszego JavaScriptu z usługą o pełnym zakresie, można uruchomić hostowanie web.dev za pomocą prostego serwera statycznego do testów. Witryna jest prawie całkowicie statyczna, ale mamy kilka specjalnych potrzeb, które nadal wymagają korzystania z niestandardowego serwera Node.js. Obejmują one przekierowania do nieprawidłowych domen oraz kod analizujący preferowany język użytkownika na potrzeby przyszłej internacjonalizacji.
Generacja statyczna
Każda strona web.dev jest napisana w języku Markdown. Wszystkie strony zawierają materiał wstępny, który zawiera metadane dotyczące każdego wpisu. Te metadane są przetwarzane w układzie każdej strony i na tej podstawie tworzone są nagłówki, tagi itd. Oto przykład:
---
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...
Te informacje wstępne umożliwiają zdefiniowanie dowolnych właściwości, takich jak autorzy, data publikacji i tagi. Eleventy w wygodny sposób ujawnia frontową sprawę jako dane w niemal każdej wtyczce, szablonie lub innym kontekście, w którym chcemy zrobić coś inteligentnego. Obiekt danych zawiera też to, co opisuje Eleventy jako kaskada danych, czyli różne dane pobierane z każdej strony, z układu używanego na stronie oraz z danych występujących w hierarchicznej strukturze folderów.
Każdy unikalny układ opisuje inny typ treści i może odziedziczyć elementy z innych układów. Na stronie web.dev używamy tej funkcji, aby prawidłowo wyświetlać różne typy treści (np. posty i laboratoria kodu), zachowując jednocześnie jedną najwyższą warstwę układu HTML.
Kolekcje
Eleventy zapewnia zautomatyzowany sposób tworzenia dowolnych kolekcji treści. Dzięki temu mogliśmy wprowadzić obsługę stron z przewijaniem i generować strony wirtualne (strony, które nie mają na dysku pasującego pliku Markdown) dla autorów postów. Na przykład strony autorów tworzymy za pomocą szablonu zawierającego wyrażenie dla jego adresu bezpośredniego (dzięki czemu szablon jest ponownie renderowany dla każdego autora) oraz zbioru.
W efekcie możesz mieć np. prostą stronę z wszystkimi postami Addy.
Ograniczenia
Obecnie nie możemy łatwo podłączyć się do procesu kompilacji Eleventy, ponieważ jest on deklaratywny, a nie imperatywny: opisujesz, czego oczekujesz, a nie jak chcesz to osiągnąć. Trudno jest uruchomić Eleventy jako część większego narzędzia do kompilacji, ponieważ można go wywołać tylko za pomocą interfejsu wiersza poleceń.
Szablony
web.dev używa systemu szablonów Nunjucks, który został pierwotnie opracowany przez firmę Mozilla. Nunjucks ma typowe funkcje tworzenia szablonów, takie jak pętle i warunki warunkowe, ale pozwala też nam definiować skróty generujące dalszy kod HTML lub wywołujące inne funkcje logiczne.
Podobnie jak większość zespołów tworzących strony ze statycznymi treściami, zaczęliśmy od podstaw i z czasem dodaliśmy skróty kódów – do tej pory około 20 skrótów. Większość z nich wymaga tylko generowania dodatkowego kodu HTML (w tym niestandardowych komponentów sieciowych). Oto przykład:
{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}
Wyglądać to będzie tak:
W rzeczywistości tworzy on kod HTML, który wygląda tak:
<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>
Chociaż wykracza to poza zakres tego wpisu, web.dev używa też skrótów jako rodzaju metajęzyka programowania. W skróconych kodach akceptowane są argumenty, przy czym jednym z argumentów jest zawarte w nim treści. Nie jest wymagane, aby skróty zwracały cokolwiek, więc można ich używać do tworzenia stanu lub uruchamiania innych działań. 🤔💭
Tworzenie scenariusza
Jak już wspomnieliśmy, web.dev to witryna statyczna, która może być wyświetlana i używana bez JavaScriptu oraz przez starsze przeglądarki, które nie obsługują type="module"
ani innego nowoczesnego kodu.
Jest to niezwykle ważna część naszego podejścia do udostępniania web.dev wszystkim.
Nasz kod przeznaczony do nowoczesnych przeglądarek składa się jednak z 2 głównych części:
- Kod wczytywania, który zawiera kod stanu globalnego, Analytics i routingu SPA
- kod i CSS do komponentów internetowych, które stopniowo ulepszają witrynę.
Kod bootstrap jest dość prosty: web.dev może wczytywać nowe strony jako aplikację jednostronicową (SPA), więc instalujemy globalny odbiornik, który reaguje na kliknięcia lokalnych elementów <a href="...">
.
Model SPA pomaga nam zachować stan globalny bieżącej sesji użytkownika, ponieważ w przeciwnym razie każde nowe wczytanie strony powodowałoby wywołanie wywołań do Firebase w celu uzyskania dostępu do stanu zalogowania użytkownika.
Określamy też kilka różnych punktów wejścia do naszej witryny na podstawie tego, który adres URL został wybrany, i wczytujemy odpowiedni adres za pomocą dynamicznego atrybutu import()
.
Dzięki temu zmniejsza się liczba bajtów, których potrzebują użytkownicy, zanim witryna zostanie rozszerzona o kod.
Komponenty sieciowe
Komponenty internetowe to elementy niestandardowe, które obejmują funkcje środowiska wykonawczego dostarczane w języku JavaScript i są identyfikowane za pomocą niestandardowych nazw, takich jak <web-codelab>
.
Ten projekt dobrze sprawdza się w przypadku stron głównie statycznych, takich jak web.dev: przeglądarka zarządza cyklem życia elementu podczas aktualizowania kodu HTML witryny, prawidłowo informując elementy o ich dołączeniu lub odłączeniu od strony.
Przeglądarki starsze niż HTML5 całkowicie ignorują komponenty internetowe i renderują tylko to, co pozostało w DOM.
Każdy element internetowy to klasa z metodami, takimi jak connectedCallback()
, disconnectedCallback()
i attributeChangedCallback()
.
Elementy niestandardowe web.dev w większości dziedziczą po LitElement, który stanowi prostą podstawę dla złożonych komponentów.
Chociaż web.dev używa komponentów internetowych na wielu stronach, są one najbardziej potrzebne na stronie Pomiar. Większość funkcji na tej stronie zapewniają 2 elementy:
<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>
Te elementy tworzą kolejne elementy, które dają więcej funkcji. Co ważne, te elementy stanowią tylko część naszego zwykłego kodu źródłowego Markdown, a nasz zespół ds. treści może dodawać rozszerzone funkcje do dowolnej strony, a nie tylko do węzła Measure.
Nasze komponenty internetowe najczęściej korzystają z modelu komponentu kontenera, który stał się popularny dzięki Reactowi, choć obecnie jest już nieco przestarzały.
Każdy element -container
łączy się z naszym stanem globalnym (dostarczanym przez unistore), a potem renderuje element wizualny, który z kolei renderuje rzeczywiste węzły DOM z układem stylów lub inną wbudowaną funkcjonalnością.
Nasze najbardziej złożone komponenty internetowe służą do wizualizacji globalnych działań i stanu. Na przykład web.dev umożliwia Ci przeprowadzenie audytu ulubionej witryny, a potem przejście z tej strony. Po powrocie zobaczysz, że zadanie jest nadal w toku.
Nasze proste komponenty wzbogacają statyczne treści lub tworzą niesamowite wizualizacje (np. każda wykresy liniowe to osobny <web-sparkline-chart>
), które nie mają żadnego związku ze stanem globalnym.
Porozmawiajmy
Zespół inżynierów web.dev (Rob, Ewa, Michael i Sam) przedstawi wkrótce więcej szczegółów technicznych.
Mamy nadzieję, że nasz sposób działania zainspiruje Cię do tworzenia własnych projektów. Jeśli masz pytania lub chcesz zasugerować tematy do omówienia w blogu, skontaktuj się z nami na Twitterze.