Una alternativa moderna a importScripts().
Segundo plano
Módulos de ES hace tiempo que han sido uno de los favoritos de los desarrolladores. Además de un de otros beneficios, ofrecen la promesa de un formato universal de módulo en el que se puede compartir el código una vez y se ejecutan en navegadores y en entornos de ejecución alternativos, como Node.js. Mientras que todos los navegadores modernos ofrecen compatibilidad con módulos ES, no todos ofrecen asistencia en todas partes que de que se pueda ejecutar el código. En concreto, la compatibilidad con la importación de módulos de ES dentro de un del navegador service worker está empezando a estar disponible de forma más generalizada.
En este artículo, se detalla el estado actual de la compatibilidad con módulos de ES en los service workers en todos los navegadores comunes, junto con algunos problemas que se deben evitar y las prácticas recomendadas para enviar código de service worker retrocompatible.
Casos de uso
El caso de uso ideal para módulos ES dentro de service workers es cargar un una biblioteca moderna o un código de configuración que se comparte con otros entornos de ejecución los módulos de ES compatibles.
Intentar compartir código de esta forma antes de los módulos de ES implica usar modelos “universal” de módulos, como UMD, que incluyen código estándar innecesario y la escritura de código que realizó cambios en modelos expuestos de forma global variables.
Las secuencias de comandos importadas a través de módulos de ES pueden activar el service worker
actualización
de flujo si su contenido cambia, que coincide con el
comportamiento
de
importScripts()
Limitaciones actuales
Solo importaciones estáticas
Los módulos de ES se pueden importar de dos maneras:
de forma estática
con la sintaxis import ... from '...'
de forma dinámica
con el método import()
. En un service worker, solo la estática
la sintaxis de gcloud.
Esta limitación es análoga a una
restricción similar
se realiza con el uso de importScripts()
. Las llamadas dinámicas a importScripts()
no suceden
funciona dentro de un service worker, y todas las llamadas a importScripts()
, que son
intrínsecamente síncrono, debe completarse antes de que el service worker complete su
Fase install
: Esta restricción garantiza que el navegador conozca
almacenar en caché implícitamente todo el código JavaScript necesario para la configuración
para implementarlos durante la instalación.
Con el tiempo, esta restricción podría eliminarse, y ES importaciones de módulos es posible que estén permitidos. Por ahora, asegúrate de usar solo la sintaxis estática dentro de un service worker.
¿Qué ocurre con otros trabajadores?
Compatibilidad con
Módulos de ES en "dedicated" trabajadores, es decir, aquellos
construido con new Worker('...', {type: 'module'})
, es más generalizada y
es compatible con Chrome y Edge desde
versión 80, así como
versiones recientes de Safari.
Las importaciones de módulos de ES estáticas y dinámicas se admiten en trabajadores dedicados.
Chrome y Edge admiten módulos ES compatibles en trabajadores compartidos desde la versión 83, pero no otro navegador ofrece asistencia en este momento.
No se admite la importación de mapas.
Importar mapas permitir entornos de ejecución para reescribir especificadores de módulos para, por ejemplo, anteponer al URL de una CDN preferida desde la que se pueden cargar los módulos de ES.
Mientras que Chrome y Edge versión 89 y posteriores admiten la importación de mapas, actualmente no se puede usar con el servicio trabajadores.
Navegadores compatibles
Los módulos de ES en los service workers son compatibles con Chrome y Edge a partir de versión 91.
Safari agregó compatibilidad Versión de la Versión preliminar de tecnología 122, y los desarrolladores deberían esperar que esta funcionalidad se lance en la versión de Safari en el futuro.
Ejemplo de código
Este es un ejemplo básico de cómo usar un módulo de ES compartido en el window
de una app web.
y registra un service worker que usa el mismo módulo 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);
// ...
})());
});
Compatibilidad con versiones anteriores
El ejemplo anterior funcionaría bien si todos los navegadores fueran compatibles con los módulos ES en service workers, pero al momento de escribir este no es el caso.
Para adaptarse a los navegadores que no tienen compatibilidad integrada, puedes ejecutar tu
de Terraform mediante un
Agrupador compatible con módulos de ES para crear un
que incluya todo el código del módulo intercalado, y funcionará
navegadores anteriores. De manera alternativa, si los módulos que intentas importar son
ya está disponible, incluida en
IIFE o
UMD, puedes importarlos usando
importScripts()
Una vez que tengas disponibles dos versiones de tu service worker; una que use ES módulos y el otro que no, deberás detectar cuál es la configuración que el navegador admite y registra la secuencia de comandos del service worker correspondiente. Los mejores las prácticas para detectar la asistencia se encuentran en constante cambio, pero puede seguir debate en esta Problema de GitHub para recomendaciones.
_Foto de Vlado Paunovic en Unsplash_