Les service workers agissent comme des serveurs proxy qui gèrent les requêtes réseau au sein de
votre application. Cela rend possible le fonctionnement hors-ligne de votre application, mais même
si vous n’avez pas besoin de support hors-ligne (ou si vous ne pouvez pas réalistiquement
l’implémenter à cause du type d’application que vous développez), il est souvent utile d’utiliser
les service workers pour accélérer la navigation en pré-cachant vos JS et CSS compilés.
Dans SvelteKit, si vous avez un fichier src/service-worker.js (ou src/service-worker/index.js),
celui-ci sera compilé et automatiquement activé.
Au sein du service worker
Au sein du service worker vous avez accès au module $service-worker, qui
vous fournit les chemins vers tous les assets statiques, fichiers compilés et pages prérendues. Vous
avez également accès à la chaîne de caractères représentant la version de l’application, que vous
pouvez utiliser pour créer un nom de cache unique, ainsi qu’à la base du chemin de déploiement. Si
votre configuration Vite précise l’option define (utilisé pour le remplacement de variables
globales), celle-ci sera appliquée aux service workers ainsi qu’à vos fichiers compilés de serveur
et de client.
L’exemple suivant met en cache l’application compilée et tout fichier dans le dossier static de
manière agressive, et met en cache toute autre requête lorsqu’elles se produisent. Ceci rend de
facto toute page visitée disponible en mode hors-ligne.
src/service-worker
// Désactive l'accès au types du DOM comme `HTMLElement` qui ne sont pas disponibles
// dans un service worker et instancie les variables globales pertinentes
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />// Assure que l'import de `$service-worker` soit correctement typé
/// <reference types="@sveltejs/kit" />
// Uniquement nécessaire si vous avez un import depuis `$env/static/public`
/// <reference types="../.svelte-kit/ambient.d.ts" />import{build(alias)constbuild:string[]importbuild
An array of URL strings representing the files generated by Vite, suitable for caching with cache.addAll(build).
During development, this is an empty array.
An array of URL strings representing the files in your static directory, or whatever directory is specified by config.kit.files.assets. You can customize which files are included from static directory using config.kit.serviceWorker.files
See config.kit.version. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
reference}from'$service-worker';// Ceci donne à `self` le typage correctconstselfconstself:ServiceWorkerGlobalScope=/**@type{ServiceWorkerGlobalScope}*/(/**@type{unknown}*/(globalThismoduleglobalThis.selfvarself:Window&typeofglobalThis
The Window.self read-only property returns the window itself, as a WindowProxy. It can be used with dot notation on a window object (that is, window.self) or standalone (self). The advantage of the standalone notation is that a similar notation exists for non-window contexts, such as in Web Workers. By using self, you can refer to the global scope in a way that will work not only in a window context (self will resolve to window.self) but also in a worker context (self will then resolve to WorkerGlobalScope.self).
The self read-only property of the WorkerGlobalScope interface returns a reference to the WorkerGlobalScope itself. Most of the time it is a specific scope like DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, or ServiceWorkerGlobalScope.
));// Crée un nom de cache unique pour ce déploiementconstCACHEconstCACHE:string=`cache-${version(alias)constversion:stringimportversion
See config.kit.version. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
An array of URL strings representing the files generated by Vite, suitable for caching with cache.addAll(build).
During development, this is an empty array.
An array of URL strings representing the files in your static directory, or whatever directory is specified by config.kit.files.assets. You can customize which files are included from static directory using config.kit.serviceWorker.files
reference// tout ce qui est dans `static`];selfconstself:ServiceWorkerGlobalScope.addEventListener(method)ServiceWorkerGlobalScope.addEventListener<"install">(type:"install",listener:(this:ServiceWorkerGlobalScope,ev:ExtendableEvent)=>any,options?:boolean|AddEventListenerOptions):void(+1overload)
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('install',(event(parameter)event:ExtendableEvent)=>{// Crée un nouveau cache et y ajoute tous les fichiersasyncfunctionaddFilesToCache(localfunction)addFilesToCache():Promise<void>(){constcacheconstcache:Cache=awaitcachesvarcaches:CacheStorage
The addAll() method of the Cache interface takes an array of URLs, retrieves them, and adds the resulting response objects to the given cache. The request objects created during retrieval become keys to the stored response operations.
The ExtendableEvent.waitUntil() method tells the event dispatcher that work is ongoing. It can also be used to detect whether that work was successful. In service workers, waitUntil() tells the browser that work is ongoing until the promise settles, and it shouldn't terminate the service worker if it wants that work to complete.
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('activate',(event(parameter)event:ExtendableEvent)=>{// Supprime du disque les données précédemment mises en cacheasyncfunctiondeleteOldCaches(localfunction)deleteOldCaches():Promise<void>(){for(constkeyconstkey:stringofawaitcachesvarcaches:CacheStorage
The keys() method of the CacheStorage interface returns a Promise that will resolve with an array containing strings corresponding to all of the named Cache objects tracked by the CacheStorage object in the order they were created. Use this method to iterate over a list of all Cache objects.
The delete() method of the CacheStorage interface finds the Cache object matching the cacheName, and if found, deletes the Cache object and returns a Promise that resolves to true. If no Cache object is found, it resolves to false.
The ExtendableEvent.waitUntil() method tells the event dispatcher that work is ongoing. It can also be used to detect whether that work was successful. In service workers, waitUntil() tells the browser that work is ongoing until the promise settles, and it shouldn't terminate the service worker if it wants that work to complete.
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('fetch',(event(parameter)event:FetchEvent)=>{// ignore les requêtes POST, etcif(event(parameter)event:FetchEvent.request(property)FetchEvent.request:Request
The request read-only property of the FetchEvent interface returns the Request that triggered the event handler.
The URL interface is used to parse, construct, normalize, and encode URLs. It works by providing properties which allow you to easily read and modify the components of a URL.
(CACHEconstCACHE:string);// les fichiers `build`/`files` peuvent toujours être servis depuis le cacheif(ASSETSconstASSETS:string[].includes(method)Array<string>.includes(searchElement:string,fromIndex?:number):boolean
Determines whether an array includes a certain element, returning true or false as appropriate.
searchElement
The element to search for.
fromIndex
The position in this array at which to begin searching for searchElement.
The pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
The match() method of the Cache interface returns a Promise that resolves to the Response associated with the first matching request in the Cache object. If no match is found, the Promise resolves to undefined.
The pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
);if(responseconstresponse:Response|undefined){returnresponseconstresponse:Response;}}// pour tout le reste, essayer d'abord le réseau, mais// se reporter au cache si le réseau est indisponibletry{constresponseconstresponse:Response=awaitfetchfunctionfetch(input:string|URL|Request,init?:RequestInit):Promise<Response>(+2overloads)
); // si nous sommes hors-ligne, fetch peut renvoyer une valeur qui n'est pas une Response
// plutôt que de lever une erreur — and nous ne pouvons pas passer cette non-Response à
// respondWithif(!(responseconstresponse:ResponseinstanceofResponsevarResponse:{new(body?:BodyInit|null,init?:ResponseInit):Response;prototype:Response;error():Response;json(data:any,init?:ResponseInit):Response;redirect(url:string|URL,status?:number):Response;}
The Response interface of the Fetch API represents the response to a request.
)){thrownewErrorvarError:ErrorConstructornew(message?:string,options?:ErrorOptions)=>Error(+1overload)('la réponse de fetch est invalide');}if(responseconstresponse:Response.status(property)Response.status:number
The status read-only property of the Response interface contains the HTTP status codes of the response.
The get() method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. If the requested header doesn't exist in the Headers object, it returns null.
Returns true if searchString appears as a substring of the result of converting this
object to a String, at one or more positions that are
greater than or equal to position; otherwise, returns false.
searchString
search string
position
If position is undefined, 0 is assumed, so as to search all of the String.
The match() method of the Cache interface returns a Promise that resolves to the Response associated with the first matching request in the Cache object. If no match is found, the Promise resolves to undefined.
);if(responseconstresponse:Response|undefined){returnresponseconstresponse:Response;} // s'il n'y a pas de cache, lever une erreur
// puisqu'il n'y a rien à répondre à cette requêtethrowerr(localvar)err:unknown;}}event(parameter)event:FetchEvent.respondWith(method)FetchEvent.respondWith(r:Response|PromiseLike<Response>):void
The respondWith() method of FetchEvent prevents the browser's default fetch handling, and allows you to provide a promise for a Response yourself.
// Désactive l'accès au types du DOM comme `HTMLElement` qui ne sont pas disponibles
// dans un service worker et instancie les variables globales pertinentes
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />// Assure que l'import de `$service-worker` soit correctement typé
/// <reference types="@sveltejs/kit" />
// Uniquement nécessaire si vous avez un import depuis `$env/static/public`
/// <reference types="../.svelte-kit/ambient.d.ts" />import{build(alias)constbuild:string[]importbuild
An array of URL strings representing the files generated by Vite, suitable for caching with cache.addAll(build).
During development, this is an empty array.
An array of URL strings representing the files in your static directory, or whatever directory is specified by config.kit.files.assets. You can customize which files are included from static directory using config.kit.serviceWorker.files
See config.kit.version. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
reference}from'$service-worker';// Ceci donne à `self` le typage correctconstselfconstself:ServiceWorkerGlobalScope=globalThismoduleglobalThis.selfvarself:Window&typeofglobalThis
The Window.self read-only property returns the window itself, as a WindowProxy. It can be used with dot notation on a window object (that is, window.self) or standalone (self). The advantage of the standalone notation is that a similar notation exists for non-window contexts, such as in Web Workers. By using self, you can refer to the global scope in a way that will work not only in a window context (self will resolve to window.self) but also in a worker context (self will then resolve to WorkerGlobalScope.self).
The self read-only property of the WorkerGlobalScope interface returns a reference to the WorkerGlobalScope itself. Most of the time it is a specific scope like DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, or ServiceWorkerGlobalScope.
The ServiceWorkerGlobalScope interface of the Service Worker API represents the global execution context of a service worker.
Available only in secure contexts.
;// Crée un nom de cache unique pour ce déploiementconstCACHEconstCACHE:string=`cache-${version(alias)constversion:stringimportversion
See config.kit.version. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
An array of URL strings representing the files generated by Vite, suitable for caching with cache.addAll(build).
During development, this is an empty array.
An array of URL strings representing the files in your static directory, or whatever directory is specified by config.kit.files.assets. You can customize which files are included from static directory using config.kit.serviceWorker.files
reference// tout ce qui est dans `static`];selfconstself:ServiceWorkerGlobalScope.addEventListener(method)ServiceWorkerGlobalScope.addEventListener<"install">(type:"install",listener:(this:ServiceWorkerGlobalScope,ev:ExtendableEvent)=>any,options?:boolean|AddEventListenerOptions):void(+1overload)
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('install',(event(parameter)event:ExtendableEvent)=>{// Crée un nouveau cache et y ajoute tous les fichiersasyncfunctionaddFilesToCache(localfunction)addFilesToCache():Promise<void>(){constcacheconstcache:Cache=awaitcachesvarcaches:CacheStorage
The addAll() method of the Cache interface takes an array of URLs, retrieves them, and adds the resulting response objects to the given cache. The request objects created during retrieval become keys to the stored response operations.
The ExtendableEvent.waitUntil() method tells the event dispatcher that work is ongoing. It can also be used to detect whether that work was successful. In service workers, waitUntil() tells the browser that work is ongoing until the promise settles, and it shouldn't terminate the service worker if it wants that work to complete.
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('activate',(event(parameter)event:ExtendableEvent)=>{// Supprime du disque les données précédemment mises en cacheasyncfunctiondeleteOldCaches(localfunction)deleteOldCaches():Promise<void>(){for(constkeyconstkey:stringofawaitcachesvarcaches:CacheStorage
The keys() method of the CacheStorage interface returns a Promise that will resolve with an array containing strings corresponding to all of the named Cache objects tracked by the CacheStorage object in the order they were created. Use this method to iterate over a list of all Cache objects.
The delete() method of the CacheStorage interface finds the Cache object matching the cacheName, and if found, deletes the Cache object and returns a Promise that resolves to true. If no Cache object is found, it resolves to false.
The ExtendableEvent.waitUntil() method tells the event dispatcher that work is ongoing. It can also be used to detect whether that work was successful. In service workers, waitUntil() tells the browser that work is ongoing until the promise settles, and it shouldn't terminate the service worker if it wants that work to complete.
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
('fetch',(event(parameter)event:FetchEvent)=>{// ignore les requêtes POST, etcif(event(parameter)event:FetchEvent.request(property)FetchEvent.request:Request
The request read-only property of the FetchEvent interface returns the Request that triggered the event handler.
The URL interface is used to parse, construct, normalize, and encode URLs. It works by providing properties which allow you to easily read and modify the components of a URL.
(CACHEconstCACHE:string);// les fichiers `build`/`files` peuvent toujours être servis depuis le cacheif(ASSETSconstASSETS:string[].includes(method)Array<string>.includes(searchElement:string,fromIndex?:number):boolean
Determines whether an array includes a certain element, returning true or false as appropriate.
searchElement
The element to search for.
fromIndex
The position in this array at which to begin searching for searchElement.
The pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
The match() method of the Cache interface returns a Promise that resolves to the Response associated with the first matching request in the Cache object. If no match is found, the Promise resolves to undefined.
The pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
);if(responseconstresponse:Response|undefined){returnresponseconstresponse:Response;}}// pour tout le reste, essayer d'abord le réseau, mais// se reporter au cache si le réseau est indisponibletry{constresponseconstresponse:Response=awaitfetchfunctionfetch(input:string|URL|Request,init?:RequestInit):Promise<Response>(+2overloads)
); // si nous sommes hors-ligne, fetch peut renvoyer une valeur qui n'est pas une Response
// plutôt que de lever une erreur — and nous ne pouvons pas passer cette non-Response à
// respondWithif(!(responseconstresponse:ResponseinstanceofResponsevarResponse:{new(body?:BodyInit|null,init?:ResponseInit):Response;prototype:Response;error():Response;json(data:any,init?:ResponseInit):Response;redirect(url:string|URL,status?:number):Response;}
The Response interface of the Fetch API represents the response to a request.
)){thrownewErrorvarError:ErrorConstructornew(message?:string,options?:ErrorOptions)=>Error(+1overload)('la réponse de fetch est invalide');}if(responseconstresponse:Response.status(property)Response.status:number
The status read-only property of the Response interface contains the HTTP status codes of the response.
The get() method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. If the requested header doesn't exist in the Headers object, it returns null.
Returns true if searchString appears as a substring of the result of converting this
object to a String, at one or more positions that are
greater than or equal to position; otherwise, returns false.
searchString
search string
position
If position is undefined, 0 is assumed, so as to search all of the String.
The match() method of the Cache interface returns a Promise that resolves to the Response associated with the first matching request in the Cache object. If no match is found, the Promise resolves to undefined.
);if(responseconstresponse:Response|undefined){returnresponseconstresponse:Response;} // s'il n'y a pas de cache, lever une erreur
// puisqu'il n'y a rien à répondre à cette requêtethrowerr(localvar)err:unknown;}}event(parameter)event:FetchEvent.respondWith(method)FetchEvent.respondWith(r:Response|PromiseLike<Response>):void
The respondWith() method of FetchEvent prevents the browser's default fetch handling, and allows you to provide a promise for a Response yourself.
Faites attention lorsque vous mettez des choses en cache ! Dans certains cas, des données
périmées peuvent être pires que pas de données du tout en mode hors-ligne. Puisque les navigateurs
vont vider le cache s’il remplit trop, vous devriez également faire attention lorsque vous mettez
en cache des assets de grande taille comme des fichiers vidéo.
build et prerendered sont des tableaux vides lors du développement.
Activation manuelle
Vous pouvez désactiver l’activation automatique si vous avez besoin
de définir le service worker avec votre propre logique. La définition par défaut ressemble à quelque
chose comme ça :
import{dev(alias)constdev:booleanimportdev
Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The serviceWorker read-only property of the Navigator interface returns the ServiceWorkerContainer object for the associated document, which provides access to registration, removal, upgrade, and communication with the ServiceWorker.
Available only in secure contexts.
Le service worker est compilé pour la production, mais pas lors du développement.
Mettre à jour le service worker
Les navigateurs vérifient si un service worker à jour est disponible lorsqu’une navigation “de
pleine page” se produit au sein de son scope, et après des évènements fonctionnels comme push et
sync. Les clients côté client ne sont ni l’un ni l’autre, ce qui implique qu’une navigation au
sein de votre application ne va en soi provoquer un nouveau déploiement de service worker.
SvelteKit exécute
registration.update()
uniquement en tant que partie de la gestion d’erreur — si un module de route échoue à se charger ou
si une navigation résulte en un statut d’erreur, et que le polling de
version détecte que l’application a été redéployée, le service worker sera
mis à jour avant que SvelteKit ne déclenche une navigation complète pour se mettre à jour.
Si vous souhaitez que les nouveaux déploiements soient pris en compte de manière plus agressive,
vous pouvez déclencher vous-même une vérification des mises à jour — par exemple pour chaque
navigation côté client, dans votre layout racine :
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The serviceWorker read-only property of the Navigator interface returns the ServiceWorkerContainer object for the associated document, which provides access to registration, removal, upgrade, and communication with the ServiceWorker.
Available only in secure contexts.
The getRegistration() method of the ServiceWorkerContainer interface gets a ServiceWorkerRegistration object whose scope URL matches the provided client URL. The method returns a Promise that resolves to a ServiceWorkerRegistration or undefined.
The update() method of the ServiceWorkerRegistration interface attempts to update the service worker. It fetches the worker's script URL, and if the new worker is not byte-by-byte identical to the current worker, it installs the new worker. The fetch of the worker bypasses any browser caches if the previous fetch occurred over 24 hours ago.
Ceci ne va pas faire en sorte que le nouveau service worker (s’il existe) se mette en place sur la
page existante immédiatement — à la place, ce nouveau service worker sera installé en toile de fond,
et il se mettra en place dès que le nombre d’onglets gérés par le service worker actuel tombera à
zéro.
Autres solutions
L’implémentation du service worker de SvelteKit est conçue pour être simple d’usage et est
probablement une bonne solution pour la plupart des gens. Cependant, en dehors de SvelteKit,
beaucoup d’applications PWA utilisent la librairie Workbox. Si
vous êtes habitué•e à cette librairie, vous pourriez préférer l’usage du plugin PWA de
Vite.
Références
Pour plus d’informations sur les service workers de manière générale, nous recommandons la
documentation de
MDN.