11

I am using ServiceWorker and in dev mode works perfectly, my problem is that in production mode my bundle name is generated using hash, e.g. 1234das3123ad5.bundle.js, so the service worker is not caching it. My sw code looks like:

self.addEventListener('install', function(event) {
  // pre cache a load of stuff:
  event.waitUntil(
    caches.open('mycache').then(function(cache) {
      return cache.addAll([
        '/dist/bundle.js',
        '/dist/app.css',
        '/dist/index.html',
        'https://cdnjs.cloudflare.com/ajax/libs/antd/2.7.2/antd.css'
      ]);
    })
  )
});

In the docs of Cache API I dont see any example on how I can achieve that.

Obviously I could cache everything under the dist folder, having something like:

self.addEventListener('install', function(event) {
  // pre cache a load of stuff:
  event.waitUntil(
    caches.open('mycache').then(function(cache) {
      return cache.addAll([
        '/dist/',
      ]);
    })
  )
});

But I dont find it an elegant, good in long term, solution. Is it a way to have wild cards in the Cache? Something like '/dist/*.bundle.js' ?

Avraam Mavridis
  • 8,698
  • 19
  • 79
  • 133

3 Answers3

6

The web doesn't have the concept of folders, specifically there isn't a way for a browser to know all the valid URLs starting with a prefix.

The rest of your site must be handling the URL changes for revisioning assets somehow, so why not use the same solution in your service worker?

That's what I did for my blog - Django's static file manager adds the correct URLs https://jakearchibald.com/sw.js

JaffaTheCake
  • 13,895
  • 4
  • 51
  • 54
  • thx Jake, I would probably find a way with webpack to generate the correct urls on the fly. – Avraam Mavridis Feb 19 '17 at 08:58
  • so what you're saying is that the sw.js is dynamically generated/modified based on the generated bundle names through webpack or some other method like sed/awk? –  Jun 21 '17 at 02:56
  • 1
    Sure, or you could load the names using `fetch('files.json').then(r => r.json())` – JaffaTheCake Jun 23 '17 at 13:12
  • Hey @JaffaTheCake, I'm trying to cache an ajax call from datatable except the ajax call appends a random generated key of digits at the end of it, the response has this also. Caching that results in a new entry each time and never a match because the key is random each time. Do you know what I mean? If there's a way around this? – Daniel Jackson Jul 01 '18 at 18:39
1

here's a simple Node script that will create the array of filenames for you, provided you want a list of every file in your web/public directory. NOTE: you want to run this from a terminal at your public directory.

var fs = require('fs');
var path = require('path');
var util = require('util');
var walk = function(dir, done) {
    var results = [];
    fs.readdir(dir, function(err, list) {
        if (err) return done(err);
        var i = 0;
        (function next() {
            var file = list[i++];
            if (!file) return done(null, results);
            //file = dir + '/' + file;
            file = path.resolve(dir, file);
            fs.stat(file, function(err, stat) {
                if (stat && stat.isDirectory()) {
                    walk(file, function(err, res) {
                        results = results.concat(res);
                        next();
                    });
                }
                else {
                    file = file.replace('/home/ubuntu/workspace/public', '');
                    results.push(file);
                    next();
                }
            });
        })();
    });
};
var mydir = path.resolve(__dirname);
walk(mydir, function(err, results) {
    if (err) throw err;
    console.log(util.inspect(results, { maxArrayLength: null }));
});
Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
0

I was experiencing some issues with this, with a vue3 pwa. So this is not a true answer, but rather a hopefully valuable reply.

With vue3, the service worker file that is generated, includes:

importScripts(
  "/precache-manifest.\<something-something\>.js"
);

and the precache-manifest.js file that is generated, lists all the js, css and font stuff that is built when doing a "vue-cli-serve build", e.g. something like:

self.__precacheManifest = (self.__precacheManifest || []).concat([
  {
    "revision": "f715169493da60af08a445c4f7990905",
    "url": "/.htaccess"
  },
  {
    "revision": "87260e830ed912c46685c0a5432addf2",
    "url": "/.well-known/web-app-origin-association"
  },
<snip>

The workbox script then takes this list and caches the mentioned files.