Skip to content

Latest commit

 

History

History
92 lines (76 loc) · 2.77 KB

Patterns.md

File metadata and controls

92 lines (76 loc) · 2.77 KB

Patterns

👈 Go to README

👆 Back to Guides

Scope based service worker scripts

For some applications, having a mix of general and specialized service workers could be desired for organizing our origin. Depending on scope (self.registration.scope), we can configure our worker and utilize importScripts to load sets of functionality based on a given scope.

/sw.js

try {
  switch (self.registration.scope.replace(location.origin, '')) {
    case '/':
      importScripts('/sw/lifecycle.js');
      importScripts('/sw/push.js');
      break;
    case '/statics':
      importScripts('/sw/lifecycle.js');
      importScripts('/sw/sync.js');
      importScripts('/sw/caching.js');
      break;
    case '/data':
      importScripts('/sw/lifecycle.js');
      importScripts('/sw/sync.js');
      importScripts('/sw/data.js');
      break;
    case '/payments':
      importScripts('/sw/lifecycle.js');
      importScripts('/sw/payment.js');
      break;
    default:
      // any rogue or accidental installations should be immediately removed
      self.unregister();
      break;
  }
} catch (error) {
  // in the event of failure, unregister
  self.unregister();
}

When we set one entry point for all service workers operating under one origin, our definition of functionality per scope gives us a high overview of what each scope is responsible for and its dependencies. In addition, our service worker scripts become modular and composable.

It's important however to ensure that between scripts, there are no conflicts with events. As a measure to prevent this, it's important to focus on not repeating events used in the other scripts.

If the need to remove the service workers registered on multiple scopes, we can use the escapeHatch function to remove them all, or use unregister with the desired scope for selective removal.

/client.js

import {
  register,
  unregister,
  escapeHatch,
} from '@americanexpress/one-service-worker';

export async function unregisterWorkers(scope) {
  if (typeof scope === 'string' && scope) await unregister(scope);
  else await escapeHatch();
}

export async function registerWorkers() {
  const updateViaCache = 'none';

  await register('/sw.js', { scope: '/', updateViaCache });
  await register('/sw.js', { scope: '/data', updateViaCache });
  // ... others
}

The updateViaCache is important in the given scenario. By setting the value to none, we are ensuring our imported scripts in the worker are not sourced from the cache.

An advantage of scope based service workers is having the client-side decide when to register a service worker at a given scope, based on the needs of the client side component.

☝️ Return To Top