1. Witamy
W tym module dodasz do istniejącej aplikacji internetowej instancję roboczą, aby udostępniać stan między dwoma otwartymi oknami. To ósme z serii powiązanych ćwiczeń z kodem do warsztatów na temat progresywnych aplikacji internetowych. Poprzedni codelab to Service Worker Includes. To ostatni codelab z tej serii.
Czego się nauczysz
- Dodawanie udostępnianej instancji roboczej między wieloma otwartymi oknami
- Używanie Comlink do ułatwiania pracy z instancjami roboczymi
Co warto wiedzieć
- JavaScript
Wymagania
- Przeglądarka obsługująca współdzielone procesy robocze
2. Pierwsze kroki
Zacznij od sklonowania lub pobrania kodu startowego potrzebnego do ukończenia tego ćwiczenia:
Jeśli klonujesz repozytorium, upewnij się, że jesteś w gałęzi pwa06--working-with-workers
. Plik ZIP zawiera też kod tej gałęzi.
Ten kod wymaga Node.js w wersji 14 lub nowszej. Gdy kod będzie dostępny, uruchom npm ci
z wiersza poleceń w folderze kodu, aby zainstalować wszystkie potrzebne zależności. Następnie uruchom npm start
, aby uruchomić serwer programistyczny dla tego laboratorium.
Plik README.md
kodu źródłowego zawiera wyjaśnienie wszystkich rozpowszechnianych plików. Oto najważniejsze pliki, z którymi będziesz pracować w trakcie tego ćwiczenia:
Kluczowe pliki
js/preview.js
– plik JavaScript strony podglądujs/main.js
– główny plik JavaScript aplikacji
3. Tworzenie pracownika
Obecnie funkcja podglądu aplikacji internetowej wyświetla tylko najnowsze treści podczas wczytywania. Najlepiej, gdyby podczas pisania użytkownik widział podgląd na żywo. Wymaga to zebrania potencjalnie dużej ilości danych i przeniesienia ich między 2 różnymi otwartymi oknami. Z tego powodu nie chcemy tego robić w głównym wątku żadnego z otwartych okien. Zamiast tego użyjmy udostępnionego procesu roboczego.
Aby rozpocząć, utwórz plik js/worker.js
z tym kodem:
import { expose } from 'comlink';
import { marked } from 'marked';
class Compiler {
state = {
raw: '',
compiled: '',
};
subscribers = [];
async set(content) {
this.state = {
raw: content,
compiled: marked(content),
};
await Promise.all(this.subscribers.map((s) => s(this.state)));
}
subscribe(cb) {
this.subscribers.push(cb);
}
}
const compiler = new Compiler();
onconnect = (e) => expose(compiler, e.ports[0]);
Wyjaśnienie
Ten kod tworzy klasę o nazwie Compiler
, która umożliwia ustawianie treści i wywoływanie subskrypcji po skompilowaniu tych treści. Ponieważ jest to współdzielony proces roboczy, powinna być używana tylko jedna instancja tej klasy, więc tworzona jest nowa instancja Compiler
. Aby praca z tą klasą była płynna z zewnątrz procesu roboczego, używamy Comlink do udostępniania instancji kompilatora, co pozwala nam używać wszystkich jej metod tak, jakby były zadeklarowane w kodzie, który ich używa. Ponieważ jest to współdzielony, a nie dedykowany proces roboczy, musi być dostępny dla wszystkich połączeń.
4. Wysyłanie treści do wykonawcy
Po utworzeniu procesu roboczego musimy przesłać do niego treści. Aby to zrobić, zaktualizuj js/main.js
w ten sposób:
- Zaimportuj eksport o nazwie
wrap
zcomlink
- Utwórz nowy moduł Shared Worker o nazwie
worker
, ustaw jego typ namodule
i wskaż go za pomocą wzorcanew URL
(new URL('./worker.js', import.meta.url)
). - Utwórz zmienną
compiler
, którawrap
worker.port
- W funkcji aktualizacji edytora (
editor.onUpdate
) po zapisaniu treści w bazie danych poczekaj na zakończenie działania funkcjicompiler.set
, przekazując do niej treść.
Wyjaśnienie
Zawijanie eksportu Comlink umożliwia używanie np. udostępnionych metod klasy tak, jakby nie były udostępniane poza granicami procesu roboczego, z wyjątkiem tego, że wszystko jest teraz asynchroniczne. Ponieważ jest to współdzielony, a nie dedykowany proces roboczy, Comlink musi opakować port procesu roboczego, a nie sam proces roboczy. Teraz, gdy tylko wprowadzisz zmiany w edytorze, treść zostanie wysłana do procesu roboczego, aby ją przetworzyć.
5. Aktualizowanie strony podglądu
Ostatnim krokiem jest przeniesienie skompilowanej treści z udostępnionego pracownika do podglądu. Konfiguracja jest w dużej mierze taka sama, ale ponieważ funkcje nie mogą być przekazywane między granicami procesu roboczego, zamiast nich należy użyć proxy funkcji. Comlink znowu przychodzi z pomocą. Zaktualizuj js/preview.js
, aby:
- Zaimportuj nazwane eksporty
wrap
iproxy
zcomlink
- Utwórz i opakuj współdzielony element roboczy tak jak w
js/main.js
. - Wywołaj metodę
subscribe
kompilatora za pomocą funkcji proxy, która ustawia właściwośćcompiled
danych przychodzących na wewnętrzny kod HTML obszaru podglądu.
Gdy to zrobisz, otwórz podgląd, zacznij pisać w edytorze i obserwuj, jak Twój kod Markdown jest automatycznie kompilowany i pojawia się w czasie rzeczywistym w obszarze podglądu, a wszystko to bez blokowania głównego wątku żadnej ze stron.
6. Gratulacje!
Wiesz już, jak używać współdzielonego procesu roboczego do udostępniania stanu między wieloma instancjami PWA.