ES-Module in Service Workern

Eine moderne Alternative zu importScripts().

Hintergrund

ES-Module sind schon seit geraumer Zeit bei Entwicklern beliebt. Neben einer Anzahl weiterer Vorteile, Sie bieten das Versprechen eines universellen Modulformats, in dem gemeinsam genutzter Code einmal veröffentlicht und in Browsern und alternativen Laufzeiten wie Node.js Während alle modernen Browser Support für ES-Module ist nicht überall verfügbar, ausgeführt werden kann. Insbesondere die Unterstützung für den Import von ES-Modulen innerhalb eines des Browsers Service Worker in immer mehr Ländern ausgeweitet.

In diesem Artikel wird der aktuelle Stand der Unterstützung von ES-Modulen in Service Workern beschrieben in gängigen Browsern angezeigt, sowie Tipps, die Sie vermeiden sollten, und Best Practices für den Versand abwärtskompatibler Service Worker-Code.

Anwendungsfälle

Der ideale Anwendungsfall für ES-Module innerhalb von Service Workern ist das Laden eines eine moderne Bibliothek oder Konfigurationscode verwenden, der auch mit anderen Laufzeiten ES-Module unterstützt.

Der Versuch, Code auf diese Weise vor ES-Modulen mit älteren "universal" wie UMD, die folgende Zeichen enthalten: und Code schreiben, durch den Änderungen an global zugänglichen Variablen.

Über ES-Module importierte Skripts können den Service Worker auslösen Update wenn sich die Inhalte ändern, sodass sie Verhalten von importScripts()

Aktuelle Beschränkungen

Nur statische Importe

ES-Module können auf zwei Arten importiert werden: statisch, mithilfe der import ... from '...'-Syntax oder dynamisch, mit der Methode import(). Innerhalb eines Service Workers werden nur die statischen Syntax wird derzeit unterstützt.

Diese Einschränkung ist analog zu einer ähnliche Einschränkung auf Nutzung des importScripts() gesetzt. Dynamische Aufrufe von importScripts() haben keine die in einem Service Worker arbeiten, sowie alle importScripts()-Aufrufe, von Natur aus synchron, muss abgeschlossen sein, bevor der Service Worker seine install. Diese Einschränkung stellt sicher, dass der Browser den gesamten JavaScript-Code, der für den Service Worker erforderlich ist, während der Installation.

Letztendlich könnte diese Einschränkung aufgehoben werden und dynamische ES Modulimporte möglicherweise zulässig. Stellen Sie vorerst sicher, dass Sie nur die statische Syntax innerhalb der Service Worker.

Was ist mit anderen Arbeitern?

Unterstützung für ES-Module in „dediziert“ Worker: Diese konstruiert mit new Worker('...', {type: 'module'}) – ist weiter verbreitet und in Chrome und Edge unterstützt, Version 80 und aktuellen Versionen von Safari Sowohl statische als auch dynamische ES-Modulimporte werden in dedizierten Workern unterstützt.

Chrome und Edge haben unterstützte ES-Module in gemeinsame Worker seit Version 83, aber nicht andere Browser bieten derzeit Unterstützung an.

Keine Unterstützung für das Importieren von Karten

Karten importieren Laufzeitumgebungen, um Modulspezifizierer umzuschreiben, um beispielsweise dem URL eines bevorzugten CDN, aus dem die ES-Module geladen werden können.

Während Chrome und Edge Version 89 und höher unterstützt das Importieren von Karten, kann nicht mit diesem Dienst verwendet werden. Arbeiter.

Unterstützte Browser

ES-Module in Service Workern werden in Chrome und Edge unterstützt, beginnend mit Version 91.

Safari wird jetzt auch in der Technologievorschau 122, und Entwickler sollten diese Funktion in der stabilen Version von Safari in Zukunft installieren.

Beispielcode

Dies ist ein einfaches Beispiel für die Verwendung eines freigegebenen ES-Moduls im window einer Webanwendung und einen Service Worker registrieren, der dasselbe ES-Modul verwendet:

// 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);
    // ...
  })());
});

Abwärtskompatibilität

Das obige Beispiel würde gut funktionieren, wenn alle Browser ES-Module in Service Workers erhalten, aber zum jetzigen Zeitpunkt ist das nicht der Fall.

Um auch Browser ohne integrierte Unterstützung zu berücksichtigen, können Sie Service Worker-Skript über eine ES-Modulkompatibler Bundler zum Erstellen eines Service Worker, der den gesamten Modulcode inline einfügt und in mit älteren Browsern. Wenn die zu importierenden Module bereits im Set verfügbar IIFE oder UMD-Formaten können Sie sie mit importScripts()

Sobald Ihnen zwei Versionen Ihres Service Workers – eine mit ES – verfügbar sind und für andere nicht: Sie müssen ermitteln, wie hoch die aktuellen Browser unterstützt, und registrieren Sie das entsprechende Service Worker-Skript. Das Beste dass sich die Verfahren zur Erkennung von Support derzeit noch ändern. Sie können sich jedoch Diskussion in diesem GitHub-Problem für Empfehlungen.

_Foto von Vlado Paunovic auf Unsplash_