web-dev-qa-db-fra.com

Existe-t-il un moyen de mettre en cache tous les fichiers du dossier / chemin d'accès défini dans le service worker?

Dans Service Worker, je peux définir un tableau de ressources qui sont mises en cache lors du démarrage de Service Worker mentionné ci-dessous:

self.addEventListener('install', event => {
    event.waitUntil(caches.open('static-${version}')
        .then(cache => cache.addAll([
            '/styles.css',
            '/script.js'
        ]))
    );
});

Comment puis-je définir un chemin/répertoire dans Service Worker, de sorte qu'au lieu d'écrire le nom de tous les fichiers, Service Worker sélectionne tous les fichiers du chemin/répertoire donné et les ajoute tous dans le cache?

7
Mohd Yasin

Ce n'est pas possible. Le SW (ou le navigateur, d'ailleurs) n'a aucune idée des fichiers d'un chemin spécifique sur le serveur Web. Vous devez donner les noms des fichiers que vous souhaitez mettre en cache. Plus sur le même problème ici.

Utilisez-vous des outils de génération pour générer automatiquement la liste des fichiers? Sinon, vous devriez probablement :)

ÉDITER:

Workbox est l'une des bibliothèques les plus utilisées pour les outils SW. Ils offrent à la fois mise en cache à l'exécution et mise en cache des actifs. Ils ont également des plugins d'outils de construction pour, par exemple. Webpack et Gulp.

La mise en cache à l'exécution fonctionne en donnant l'actif à partir du cache s'il existe et en le mettant à jour de toute façon à partir du serveur. Fondamentalement, chaque nouvel actif sera initialement demandé au réseau, puis renvoyé du cache lors des demandes suivantes.

EDIT2:

Oui, vous pouvez utiliser Workbox sans NPM dans une certaine mesure. Vous devez exécuter des scripts NPM, etc. pour rassembler les noms de fichiers pour les fichiers à mettre en cache MAIS vous pouvez toujours implémenter la mise en cache d'exécution simplement en important le script Workbox.js dans votre fichier SW manuscrit.

Juste en disant

importScript("https://unpkg.com/[email protected]/build/importScripts/workbox-sw.prod.v2.1.0.js") 

En haut de votre logiciel, la dernière version (à partir de maintenant) de Workbox est importée. Vous pouvez voir que c'est ce qui se passe dans l'exemple de mise en cache d'exécution ici aussi .

Vous pouvez également télécharger le fichier .js ci-dessus et le placer sur votre propre serveur et l'importer à partir d'un chemin relatif à la place.

3
pate

Mise en cache d'exécution à l'aide de Workbox sw.

service-worker.js:

importScripts('https://unpkg.com/[email protected]/build/importScripts/workbox-sw.dev.v0.0.2.js');
importScripts('https://unpkg.com/[email protected]/build/importScripts/workbox-runtime-caching.prod.v1.3.0.js');
importScripts('https://unpkg.com/[email protected]/build/importScripts/workbox-routing.prod.v1.3.0.js');

const assetRoute = new workbox.routing.RegExpRoute({
    regExp: new RegExp('^http://localhost:8081/jobs/static/*'),
    handler: new workbox.runtimeCaching.CacheFirst()
});

const router = new workbox.routing.Router();
//router.addFetchListener();
router.registerRoutes({routes: [assetRoute]});
router.setDefaultHandler({
    handler: new workbox.runtimeCaching.CacheFirst()
});

Script dans mon fichier html pour charger le travailleur Servcie.

<script>
    if ('serviceWorker' in navigator) {
        window.addEventListener('load', function() {
            navigator.serviceWorker.register('http://localhost:8081/jobs/static/service-worker.js?v=4').then(function(registration) {
            // Registration was successful
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }, function(err) {
            // registration failed :(
            console.log('ServiceWorker registration failed: ', err);
            });
        });
    }
</script>
1
Mohd Yasin

Oui, vous pouvez. J'ai également ce genre de problème et je trouve une solution intéressante en utilisant performance. Voici mon sw.js:

const KEY = 'key';

self.addEventListener('install', (event) => {
    event.waitUntil(self.skipWaiting());
});

self.addEventListener('message', (event) => {
    if (event.data.type === 'CACHE_URLS') {
        event.waitUntil(
            caches.open(KEY)
                .then( (cache) => {
                    return cache.addAll(event.data.payload);
                })
        );
    }
});

Voici mon main.js:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js', { scope: '/' })
        .then((registration) => {
            const data = {
                type: 'CACHE_URLS',
                payload: [
                    location.href,
                    ...performance.getEntriesByType('resource').map((r) => r.name)
                ]
            };
            registration.installing.postMessage(data);
        })
        .catch((err) => console.log('SW registration FAIL:', err));
}

Par cela, vous pouvez également ajouter un filtre qui mettra en cache un chemin spécifique.

1
Jahongir