Moduły ES w skryptach service worker

Nowoczesna alternatywa dla metody importScripts().

Wprowadzenie

Moduły ES są od jakiegoś czasu ulubionym miejscem dla programistów. Zapewniają one wiele innych korzyści, ale zapewniają też uniwersalny format modułów, dzięki któremu udostępniony kod można opublikować raz i uruchomić w przeglądarkach i alternatywnych środowiskach wykonawczych, np. Node.js. Wszystkie nowoczesne przeglądarki obsługują niektóre moduły ES, ale nie wszystkie umożliwiają obsługę każdego miejsca, w którym można uruchomić dany kod. W szczególności rozszerzamy obsługę importowania modułów ES do skryptu service worker przeglądarki.

W tym artykule szczegółowo opisujemy bieżący stan obsługi modułu ES w mechanizmach service worker w różnych popularnych przeglądarkach, a także pokazujemy, jakich błędów należy unikać, a także sprawdzone metody związane z wysyłaniem kodu tego mechanizmu.

Przykłady zastosowań

Idealnym przypadku użycia modułów ES w mechanizmach Service Worker jest wczytywanie nowoczesnej biblioteki lub kodu konfiguracji, które są udostępniane innym środowiskom wykonawczym, które obsługują moduły ES.

Próba udostępnienia kodu w ten sposób przed wprowadzeniem modułów ES wymagała używania starszych „uniwersalnych” formatów modułów, takich jak UMD, które zawierają zbędny ciąg stały, oraz pisanie kodu, który wprowadzał zmiany w zmiennych dostępnych globalnie.

Skrypty zaimportowane przez moduły ES mogą aktywować proces aktualizacji skryptu service worker, jeśli ich zawartość ulegnie zmianie, zgodnie z działaniem metody importScripts().

Bieżące ograniczenia

Tylko importy statyczne

Moduły ES można importować na 2 sposoby: statycznie, za pomocą składni import ... from '...' lub dynamicznie, korzystając z metody import(). Obecnie w skrypcie service worker obsługiwana jest tylko składnia statyczna.

Odpowiada to podobnemu ograniczeniu nakładanemu na korzystanie z importScripts(). Wywołania dynamiczne importScripts() nie działają w skrypcie service worker, a wszystkie wywołania importScripts(), które są z natury synchroniczne, muszą zakończyć się przed zakończeniem fazy install. To ograniczenie daje pewność, że przeglądarka wie o całym kodzie JavaScript potrzebnym do implementacji skryptu service worker podczas instalacji i może ją domyślnie zapisywać w pamięci podręcznej.

Po pewnym czasie to ograniczenie może zostać zniesione i może być możliwe dynamiczne importowanie modułów ES. Na razie używaj składni statycznej w skrypcie service worker.

Co z innymi pracownikami?

Obsługa modułów ES w specjalnych instancjach roboczych (stworzonych przy użyciu new Worker('...', {type: 'module'})) jest bardziej powszechna i jest obsługiwana w Chrome i Edge od wersji 80, a także najnowszych wersji Safari. W dedykowanych instancjach roboczych obsługiwane są zarówno statyczne, jak i dynamiczne importowanie modułów ES.

Przeglądarki Chrome i Edge obsługiwały moduły ES w współdzielonych instancjach roboczych od wersji 83, ale żadna inna przeglądarka obecnie nie oferuje pomocy technicznej.

Brak obsługi map importu

Importowanie map pozwala środowiskom wykonawczym przepisywać specyfikatory modułów, np. na początku adresu URL preferowanej sieci CDN, z której można ładować moduły ES.

Chociaż Chrome i Edge w wersjach 89 i nowszych obsługują importowanie map, obecnie nie można ich używać z skryptami service worker.

Obsługiwane przeglądarki

Moduły ES w mechanizmach Service Worker są obsługiwane w Chrome i Edge od wersji 91.

Safari dodała obsługę w wersji przedpremierowej technologii w wersji 122, a deweloperzy powinni spodziewać się, że w przyszłości udostępnimy tę funkcję w stabilnej wersji Safari.

Przykładowy kod

Oto podstawowy przykład wykorzystania udostępnionego modułu ES w kontekście window aplikacji internetowej oraz zarejestrowania skryptu service worker, który korzysta z tego samego modułu ES:

// Inside config.js:
export const cacheName = 'my-cache';
// Inside your web app:
<script type="module">
  import {cacheName} from './config.js';
  // Do something with cacheName.

  await navigator.serviceWorker.register('es-module-sw.js', {
    type: 'module',
  });
</script>
// Inside es-module-sw.js:
import {cacheName} from './config.js';

self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open(cacheName);
    // ...
  })());
});

Zgodność wsteczna

Powyższy przykład zadziałał, jeśli wszystkie przeglądarki obsługiwały moduły ES w skryptach service worker, ale w tej chwili jest inaczej.

Aby zapewnić obsługę przeglądarek, które nie mają wbudowanej obsługi, możesz uruchomić skrypt skryptu service worker za pomocą pakietu zgodnej z modułami ES w celu utworzenia skryptu service worker, który będzie zawierał cały kod modułu i działał w starszych przeglądarkach. Jeśli moduły, które próbujesz zaimportować, są już dostępne w pakietach w formacie IIFE lub UMD, możesz je też zaimportować za pomocą metody importScripts().

Gdy dostępne będą 2 wersje skryptu service worker – jedna z modułów ES, a druga nie – musisz określić, co obsługuje bieżąca przeglądarka i zarejestrować odpowiedni skrypt skryptu service worker. Sprawdzone metody wykrywania pomocy technicznej obecnie się zmieniają, ale możesz zapoznać się z rekomendacjami w tym problemie na GitHubie.

_Fot. Vlado Paaunovic, Unsplash_