Alternative moderne à importScripts().
Contexte
Modules ES est l'une des applications préférées des développeurs depuis un moment. En plus d'un de nombreux autres avantages, ils offrent la promesse d'un format de module universel dans lequel le code partagé peut être publiées une seule fois et s'exécutent dans des navigateurs et d'autres environnements d'exécution, comme Node.js Alors que tous les navigateurs récents proposent une assistance pour les modules ES, mais pas partout où peut être exécuté. Plus précisément, la prise en charge de l'importation de modules ES à l'intérieur d'un navigateur service worker commence tout juste à être plus largement disponible.
Cet article décrit l'état actuel de la compatibilité du module ES avec les service workers. des navigateurs courants, ainsi que quelques pièges à éviter et les bonnes pratiques l'envoi de code de service worker compatible avec les versions antérieures.
Cas d'utilisation
Le cas d'utilisation idéal des modules ES dans les service workers consiste à charger une bibliothèque ou un code de configuration moderne qui est partagé avec d'autres environnements d'exécution prend en charge les modules ES.
Tentative de partage de code de cette manière avant les modules ES impliquant d'utiliser d'anciennes "universel" formats de module comme UMD, qui incluent code récurrent inutile, et écriture de code apportant des modifications à des ressources exposées de manière globale variables.
Les scripts importés via des modules ES peuvent déclencher le service worker
mise à jour
en cas de modification du contenu,
comportement
de
importScripts()
Limites actuelles
Importations statiques uniquement
Les modules ES peuvent être importés de deux manières :
de manière statique,
à l'aide de la syntaxe import ... from '...'
;
de façon dynamique,
à l'aide de la méthode import()
. Dans un service worker, seule la couche statique
est actuellement acceptée.
Cette limitation s'apparente
restriction similaire
qui est basé sur l'utilisation de importScripts()
. Les appels dynamiques à importScripts()
ne
fonctionnent dans un service worker, ainsi que tous les appels importScripts()
, qui sont
par nature synchrones, doivent s'effectuer avant que le service worker n'ait terminé
install
. Cette restriction garantit que le navigateur connaît et
mettre en cache implicitement tout le code JavaScript nécessaire au fonctionnement
lors de l'installation.
Il est possible que cette restriction soit levée, et l'ES dynamique importations de modules peuvent être autorisées. Pour l'instant, veillez à n'utiliser que la syntaxe statique à l'intérieur de un service worker.
Qu'en est-il des autres nœuds de calcul ?
Assistance pour
Modules ES dans des les nœuds de calcul, c'est-à-dire
construite avec new Worker('...', {type: 'module'})
, est plus répandue, et
est pris en charge dans Chrome et Edge depuis
version 80, ainsi que
versions récentes de Safari.
Les importations de modules ES statiques et dynamiques sont compatibles avec les nœuds de calcul dédiés.
Chrome et Edge disposent de modules ES compatibles dans nœuds de calcul partagés depuis la version 83, mais pas un autre navigateur est actuellement compatible.
Impossible d'importer des cartes
Importer des cartes permet environnements d'exécution pour réécrire les spécificateurs de module afin, par exemple, d'ajouter le préfixe URL du CDN préféré à partir duquel les modules ES peuvent être chargés.
Alors que Chrome et Edge version 89 ou ultérieure prennent en charge l'importation de cartes, ne peut pas être utilisé avec le service les nœuds de calcul.
Prise en charge des navigateurs
Les modules ES des service workers sont compatibles avec Chrome et Edge, à partir de version 91.
Safari est désormais pris en charge dans Version Preview technologique 122, et les développeurs doivent s'attendre à ce que cette fonctionnalité soit disponible dans la version stable de Safari.
Exemple de code
Voici un exemple de base d'utilisation d'un module ES partagé dans le window
d'une application Web
tout en enregistrant un service worker qui utilise le même module 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);
// ...
})());
});
Rétrocompatibilité
L'exemple ci-dessus fonctionnerait bien si tous les navigateurs acceptaient les modules ES dans mais ce n'est pas le cas à ce stade.
Pour vous adapter aux navigateurs qui ne sont pas compatibles, vous pouvez exécuter votre
de service worker via un
Bundler compatible avec le module ES pour créer un
qui inclut tout le code du module de façon intégrée et fonctionne dans
des navigateurs plus anciens. Si les modules que vous tentez d'importer sont
déjà disponible dans une offre groupée
IIFE ou
UMD, vous pouvez les importer
importScripts()
Lorsque deux versions de votre service worker sont disponibles, l'une utilisant ES modules et celui de l'autre, vous devez détecter navigateur prend en charge et enregistre le script service worker correspondant. Le meilleur les pratiques de détection de la prise en charge sont en cours de développement, mais vous pouvez suivre discussion dans ce Problème GitHub pour recommandations.
_Photo par Vlado Paunovic sur Unsplash_