Service worker won't install when I try to cache xxx.worker.js
Asked Answered
N

1

8

I have the following service worker code in my Vue app:

main.js

if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/service-worker.js').catch(function() {
    console.log('Service worker registration failed.');
  });
}

service-worker.js

let currCacheName = 'premium-poker-tools-5';

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(currCacheName).then(function(cache) {
      let promise = cache.addAll([
        '/',
        'app.js',
        'c7d016677eb7e912bc40.worker.js',
        'f328c7e2b379df12fa4c.worker.js',
        'static/logo.png',
        'static/favicon.png',
        'static/loading.svg',
        'static/cards/ace-of-clubs.png',
        'static/cards/king-of-clubs.png',
        'static/cards/queen-of-clubs.png',
        'static/cards/jack-of-clubs.png',
        'static/cards/ten-of-clubs.png',
        'static/cards/nine-of-clubs.png',
        'static/cards/eight-of-clubs.png',
        'static/cards/seven-of-clubs.png',
        'static/cards/six-of-clubs.png',
        'static/cards/five-of-clubs.png',
        'static/cards/four-of-clubs.png',
        'static/cards/three-of-clubs.png',
        'static/cards/two-of-clubs.png',
        'static/cards/ace-of-spades.png',
        'static/cards/king-of-spades.png',
        'static/cards/queen-of-spades.png',
        'static/cards/jack-of-spades.png',
        'static/cards/ten-of-spades.png',
        'static/cards/nine-of-spades.png',
        'static/cards/eight-of-spades.png',
        'static/cards/seven-of-spades.png',
        'static/cards/six-of-spades.png',
        'static/cards/five-of-spades.png',
        'static/cards/four-of-spades.png',
        'static/cards/three-of-spades.png',
        'static/cards/two-of-spades.png',
        'static/cards/ace-of-hearts.png',
        'static/cards/king-of-hearts.png',
        'static/cards/queen-of-hearts.png',
        'static/cards/jack-of-hearts.png',
        'static/cards/ten-of-hearts.png',
        'static/cards/nine-of-hearts.png',
        'static/cards/eight-of-hearts.png',
        'static/cards/seven-of-hearts.png',
        'static/cards/six-of-hearts.png',
        'static/cards/five-of-hearts.png',
        'static/cards/four-of-hearts.png',
        'static/cards/three-of-hearts.png',
        'static/cards/two-of-hearts.png',
        'static/cards/ace-of-diamonds.png',
        'static/cards/king-of-diamonds.png',
        'static/cards/queen-of-diamonds.png',
        'static/cards/jack-of-diamonds.png',
        'static/cards/ten-of-diamonds.png',
        'static/cards/nine-of-diamonds.png',
        'static/cards/eight-of-diamonds.png',
        'static/cards/seven-of-diamonds.png',
        'static/cards/six-of-diamonds.png',
        'static/cards/five-of-diamonds.png',
        'static/cards/four-of-diamonds.png',
        'static/cards/three-of-diamonds.png',
        'static/cards/two-of-diamonds.png',
        'static/feedback/1.png',
        'static/feedback/2.png',
        'static/feedback/3.png',
        'static/feedback/4.png',
        'static/feedback/flop-selector.png',
        'static/feedback/green-grid-squares.png',
        'static/feedback/user-set-range-to-simulate-to-street.png',
        'static/guides/beginners-guide/1.png',
        'static/guides/beginners-guide/2.png',
        'static/guides/beginners-guide/3.png',
        'static/guides/beginners-guide/4.png',
        'static/guides/beginners-guide/5.png',
        'static/guides/beginners-guide/6.png',
        'static/guides/beginners-guide/7.png',
        'static/guides/beginners-guide/8.png',
        'static/guides/beginners-guide/9.png',
        'static/guides/beginners-guide/10.png',
        'static/guides/beginners-guide/11.png',
        'static/guides/beginners-guide/12.png',
        'static/guides/beginners-guide/13.png',
        'static/guides/beginners-guide/14.png',
        'static/guides/beginners-guide/15.png',
        'static/guides/beginners-guide/16.png',
        'static/guides/beginners-guide/17.png',
        'static/guides/beginners-guide/18.png',
        'static/guides/beginners-guide/19.png',
        'static/guides/beginners-guide/20.png',
        'static/guides/beginners-guide/21.png',
        'static/guides/faq/double-counting/1.png',
        'static/guides/faq/hit-percentage-calculation/1.png',
        'static/guides/faq/hit-percentage-calculation/2.png',
        'static/guides/faq/hit-percentage-calculation/3.png',
        'static/guides/faq/insights/1.png',
        'static/guides/faq/insights/2.png',
        'static/guides/faq/insights/3.png',
        'static/guides/faq/insights/4.png',
        'static/guides/faq/insights/5.png',
        'static/guides/faq/insights/6.png',
        'static/guides/faq/insights/7.png',
        'static/guides/faq/insights/8.png',
        'static/guides/faq/set-checks-to-default/1.png',
        'static/guides/quick-guide/1.png',
        'static/guides/quick-guide/2.png',
        'static/guides/quick-guide/3.png',
        'static/guides/quick-guide/4.png',
        'static/guides/quick-guide/5.png',
        'static/guides/quick-guide/6.png',
        'static/guides/quick-guide/7.png',
        'static/guides/quick-guide/8.png',
        'static/guides/quick-guide/save-load-scenario.png',
        'static/home/1.png',
        'static/home/2.png',
        'static/home/3.png',
        'static/settings/equity-calculator-insights-not-visible.png',
        'static/settings/equity-calculator-insights-visible.png',
        'static/settings/outcome-analyzer-checkboxes-collapsed-1.png',
        'static/settings/outcome-analyzer-checkboxes-collapsed-2.png',
        'static/settings/outcome-analyzer-checkboxes-included-1.png',
        'static/settings/outcome-analyzer-checkboxes-included-2.png',
        'static/settings/outcome-analyzer-hands.png',
        'static/settings/outcome-analyzer-insights-not-visible.png',
        'static/settings/outcome-analyzer-insights-visible.png',
        'static/settings/saved-ranges-1.png',
        'static/settings/saved-ranges-2.png',
        'static/settings/saved-ranges-3.png',
        'static/settings/saved-ranges-4.png',
        'static/settings/included-selectors/double-slider-selector.png',
        'static/settings/included-selectors/log-double-slider-selector.png',
        'static/settings/included-selectors/saved-ranges-selector.png',
        'static/settings/included-selectors/single-slider-selector.png',
        'static/settings/included-selectors/tier-and-category-selector.png',
        'static/settings/tiers/tiers.png',
        'static/settings/visual/dont-show-num-combos-in-range.png',
        'static/settings/visual/green-grid-squares.png',
        'static/settings/visual/multicolored-grid-squares.png',
        'static/settings/visual/show-num-combos-in-range.png',
      ]).then(function () {
        console.log('Successfully cached everything.')
      }).catch(function (error) {
        console.log('Problem caching: ', error);
      });

      return promise;
    }).catch(function () {
      console.error('Error with caches.open or cache.addAll');
    })
  );
});

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys()
      .then(function getOldCachesThatBeginWithPremiumPokerToolsDash (cacheNames) {
        return cacheNames.filter(function (cacheName) {
          return cacheName.startsWith('premium-poker-tools-') && (cacheName !== currCacheName);
        });
      })
      .then(function removeOldCachesThatBeginWithPremiumPokerToolsDash (oldCachesThatBeginWithPremiumPokerToolsDash) {
        let removeCachePromises = [];

        oldCachesThatBeginWithPremiumPokerToolsDash.forEach(function (oldCacheThatBeginsWithPremiumPokerToolsDash) {
          removeCachePromises.push(caches.delete(oldCacheThatBeginsWithPremiumPokerToolsDash));
        });

        return Promise.all(removeCachePromises);
      })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function (response) {
      if (response) {
        return response;
      }

      return fetch(event.request);
    }).catch(function () {
      console.error('Error trying to match event request to cache.');
    })
  );
});

When I comment out 'c7d016677eb7e912bc40.worker.js' and 'f328c7e2b379df12fa4c.worker.js', it works fine. But when I uncomment them, here's what happens:

  • I start off going to the Dev Tools and unregistering any service workers and deleting anything in Cache Storage so that I start off with a clean slate.
  • I load localhost:8080.
  • The service worker stays in the installing state.
  • In Cache Storage, I see that c7d016677eb7e912bc40.worker.js and f328c7e2b379df12fa4c.worker.js have been successfully cached.
  • However, "Successfully cached everything." isn't being logged to the console. But "Problem caching: " isn't being logged either.

I understand that the promise you pass to event.waitUntil() lets the browser know when your install completes, and if it was successful. So clearly there is some issue going on with the promise. But I don't know what the issue is. It's not hitting the .then block or the .catch block, and when I look at Cache Storage in the Dev Tools, it appears that 'c7d016677eb7e912bc40.worker.js' and 'f328c7e2b379df12fa4c.worker.js' are being successfully cached.

Edit: I am using worker-loader. I get the feeling that the issue is related to how the worker files are loaded, but I don't see why there would be a problem, because when I go to localhost:8080/c7d016677eb7e912bc40.worker.js or localhost:8080/f328c7e2b379df12fa4c.worker.js, I get back the JS file.

Also, I have made sure that prefixes in c7d016677eb7e912bc40.worker.js and f328c7e2b379df12fa4c.worker.js are accurate. Eg. that c7d016677eb7e912bc40 and f328c7e2b379df12fa4c are accurate.

Update:

enter image description here

enter image description here

enter image description here

Nowadays answered 10/9, 2018 at 21:39 Comment(6)
What is the service worker's statue reported by chrome? is it waiting to activated with an orange icon beside itHeidiheidie
@HyyanAboFakher The status is installing, which comes before the waiting to be activated state. I added pictures to demonstrate.Nowadays
Check the URL <site>/ngsw/state that may some errors in there.Medford
@Medford I don't see any requests being made to /ngsw/state in the network tab. When I visit /ngsw/state - eg type it in to the URL bar and press enter - the response to GET /ngsw/state is just my index.html file.Nowadays
@Medford It seems that /ngsw/state is specific to service workers in the context of Angular. I am using Vue.Nowadays
@AdamZerner yes sorry it is, you may want to add that to your list of tags.Medford
S
0

This doesn't work how you think it does:

caches.open(currCacheName).then(function(cache) {
  let promise = cache.addAll([

You are defining a variable called promise here, but it doesn't replace cache, which is the promise which needs to be fulfilled.

You have a load of assets to cache and then:

 'static/settings/visual/show-num-combos-in-range.png',
      ]).then(function () {
        console.log('Successfully cached everything.')
      }).catch(function (error) {
        console.log('Problem caching: ', error);
      });

You don't return anything here, so .then won't run, but it's not an error, so .catch won't either.

Your cache gets populated, but your promise for extendableEvent.waitUntil() is never settled, so installation never completes.

Either scrap your promise variable / console.logs and return the cache.addAll like this:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(currCacheName).then(function(cache) {
      return cache.addAll([
        '/',
        'app.js',
        'static/settings/visual/show-num-combos-in-range.png',
      ])
    })
  );
});

Or make your function async, like this:

self.addEventListener('install', event => {
  event.waitUntil(async function() {
    const cache = await caches.open(currCacheName);
    await cache.addAll([
        '/',
        'app.js',
        'static/settings/visual/show-num-combos-in-range.png',
    ]);
  }());
});
Saarinen answered 20/9, 2018 at 3:48 Comment(4)
1) The return cache.addAll approach doesn't work; the same thing happens as what I described in the question with the service worker remaining in the installing state.Nowadays
2) "You are defining a variable called promise here, but it doesn't replace cache, which is the promise which needs to be fulfilled." I thought that cache is an object, not a promise, and that what needs to happen is that the .then block of caches.open needs to return something in order to trigger the caches.open promise to resolve (which would trigger event.waitUntil to finish). If so, I don't see why it would matter if you assign to the promise variable, because either way the .then block of caches.open is returning something.Nowadays
3) Even if assigning to the promise variable causes issues with caches.open, why would it cause issues with the .then and .catch blocks of cache.addAll?Nowadays
4) If there is indeed an issue with the let promise = cache.addAll approach, why does it work when I comment out c7d016677eb7e912bc40.worker.js and f328c7e2b379df12fa4c.worker.js?Nowadays

© 2022 - 2024 — McMap. All rights reserved.