Un'alternativa moderna a importScripts().
Sfondo
Moduli ES sono le preferite degli sviluppatori da un po'. Oltre a un numero di altri vantaggi, offrono la promessa di un formato di moduli universale in cui il codice condiviso possa essere una volta rilasciate ed eseguite nei browser e in runtime alternativi, Node.js. Mentre tutti i browser moderni offrono supporto per i moduli ES, non tutti offrono supporto ovunque è possibile eseguire il codice. In particolare, il supporto per l'importazione dei moduli ES all'interno di un del browser Service worker è solo agli inizi.
Questo articolo descrive in dettaglio lo stato attuale del supporto dei moduli ES nei service worker nei browser più comuni, insieme ad alcuni trucchi da evitare e le best practice che spedisce codice del service worker compatibile con le versioni precedenti.
Casi d'uso
Il caso d'uso ideale per i moduli ES all'interno dei service worker è il caricamento di un una libreria moderna o un codice di configurazione condiviso con altri runtime e supportare i moduli ES.
Il tentativo di condividere il codice in questo modo prima dei moduli ES comportava l'utilizzo di "universale" formati di moduli come UMD che includono boilerplate non necessari e la scrittura di codice che apporta modifiche agli ambienti esposti a livello globale come la codifica one-hot delle variabili categoriche.
Gli script importati tramite moduli ES possono attivare il service worker
aggiorna
in caso di variazione dei contenuti, in base ai
comportamento
di
importScripts()
.
Limitazioni attuali
Solo importazioni statiche
I moduli ES possono essere importati in due modi:
in modo statico,
utilizzando la sintassi import ... from '...'
oppure
in modo dinamico,
utilizzando il metodo import()
. All'interno di un service worker, solo lo stato
è attualmente supportata.
Questa limitazione è analoga a un
restrizione simile
effettuata in base all'utilizzo di importScripts()
. Le chiamate dinamiche a importScripts()
non
all'interno di un service worker e tutte le chiamate importScripts()
, che sono
di per sé sincrona, deve essere completata prima che il service worker completi la sua
install
fase. Questa restrizione garantisce che il browser sia a conoscenza e
memorizzare nella cache, tutto il codice JavaScript necessario per lo sviluppo
implementazione durante l'installazione.
Questa limitazione potrebbe essere revocata e lo stato dinamico di ES importazioni di moduli potrebbe essere consentito. Per il momento, assicurati di utilizzare solo la sintassi statica all'interno di un service worker.
E gli altri lavoratori?
Supporto per
Moduli ES in "dedicato" worker, ovvero
creata con new Worker('...', {type: 'module'})
, è più diffusa
è supportata in Chrome ed Edge
versione 80, oltre a
versioni recenti di Safari.
Le importazioni di moduli ES statiche e dinamiche sono supportate nei worker dedicati.
Chrome ed Edge hanno moduli ES supportati in lavoratori condivisi dalla versione 83, ma non altri browser al momento offrono assistenza.
Nessun supporto per l'importazione delle mappe
Consenti Importa mappe ambienti runtime per riscrivere gli specificatori dei moduli, ad esempio anteporre URL di una rete CDN preferita da cui è possibile caricare i moduli ES.
Mentre Chrome ed Edge versione 89 e successive supportano l'importazione di mappe, al momento non può essere utilizzato con il servizio worker.
Supporto browser
I moduli ES nei service worker sono supportati in Chrome ed Edge a partire da versione 91.
Safari ha aggiunto il supporto Versione 122 di Anteprima tecnologica, e gli sviluppatori dovrebbero aspettarsi il rilascio di questa funzionalità di Safari in futuro.
Esempio di codice
Questo è un esempio base di utilizzo di un modulo ES condiviso in window
di un'app web
di contesto, registrando al contempo un service worker che utilizza lo stesso modulo 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);
// ...
})());
});
Compatibilità con le versioni precedenti
L'esempio precedente andrebbe bene se tutti i browser supportavano i moduli ES in ai service worker, ma al momento della stesura di questo articolo non è così.
Per supportare i browser che non dispongono di supporto integrato, puoi eseguire
dello script del service worker tramite un
Bundler compatibile con il modulo ES per creare un
che includa tutto il codice del modulo in linea e che lavorerà
browser meno recenti. In alternativa, se i moduli che stai tentando di importare sono
già disponibile in bundle
IIFE o
UMD, puoi importarli utilizzando
importScripts()
.
Quando sono disponibili due versioni del service worker, una che utilizza ES moduli e l'altra che non lo fa, dovrai rilevare quale che il browser supporti e registra lo script del service worker corrispondente. Il meglio le pratiche di rilevamento dell'assistenza sono in continua evoluzione, ma puoi seguire le in questa Problema GitHub per personalizzati.
_Foto di Vlado Paunovic su Unsplash_