6.46.8 • Published 21 hours ago

@gasket/plugin-service-worker v6.46.8

Weekly downloads
35
License
MIT
Repository
github
Last release
21 hours ago

@gasket/plugin-service-worker

Service workers are scripts that run separate from the main web page and enable progressive web app features such as precaching, push notifications, and background syncing.

Installation

New apps

gasket create <app-name> --plugins @gasket/plugin-service-worker

Existing apps

npm i @gasket/plugin-service-worker

Modify plugins section of your gasket.config.js:

module.exports = {
  plugins: [
    add: [
+      '@gasket/plugin-service-worker'
    ]
  ]
}

Configuration

Options

To be set in under serviceWorker in the gasket.config.js.

  • url - (string) Name the service worker file. Default is /sw.js
  • scope - (string) From where to intercept requests. Default is /
  • content - (string) The JavaScript content to be served. While this can be initialized in the Gasket config, the expectation is it will be modified by plugins using composeServiceWorker lifecycle.
  • cacheKeys - (function[]) Optional cache key functions that accept the request object as argument and return a string.
  • cache - (object) adjust the content cache settings using the lru-cache options. By default, content will remained cached for 5 days from last request.
  • minify - (object). Minification options to be used on the composed JavaScript. Configuration for this field is passed directly to uglify-js. This is turned on in production by default. Adding minify: { } will turn on the default behavior in other environments, if specified.

Example

The defaults options for this plugin should be sufficient. However, they can be tuned as needed. A real-world use case may be for a micro-app served under a sub-path.

For example, say there is a "docs" Gasket app, served from /docs under the primary domain. For the service worker to be installed and properly scoped, the following settings would be needed:

// gasket.config.js

module.exports = {
  serviceWorker: {
    url: '/docs/server-worker.js',
    scope: '/docs',
    minify: {
      ie8: true
    }
  }
}

Lifecycles

composeServiceWorker

Allows plugins to add to the service worker script, by concatenating inline script text or loaded file data.

Example inline script

This example adds a simple listener for push notifications to the service worker content.

module.exports = {
  hooks: {
    composeServiceWorker: function (gasket, content, req) {

      // `req` allows SW content based on hostname, cookie, etc.

      return content.concat(```
self.addEventListener('push', (event) => {
  const title = 'My App Notification';
  const options = {
    body: event.data.text()
  };
  event.waitUntil(self.registration.showNotification(title, options));
});
```   )
    }
  }
}

Example loaded script

In this example, we use the market id from the request to read in a partial service worker and add it to the content.

const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);

module.exports = {
  hooks: {
    composeServiceWorker: async function (gasket, content, req) {

      const { market = 'en-US' } = req.cookies || {};
      const marketFile = `${market.toLowerCase()}.js`;

      const partial = await readFile( path.join('sw', marketFile), 'utf8');

      return content + partial;
    }
  }
}

serviceWorkerCacheKey

Allows plugins to effect the cache key based on the request.

Composing service workers can potentially be process intensive, and it is unnecessary to recompose the service worker for each unique request. This hook gathers functions which accept Request as an argument and return a string value.

Verbose example:

This example returns a function that picks off a variable from cookies.

module.exports = {
  hooks: {
    serviceWorkerCacheKey: function (gasket) {
      return function marketCacheKey(req) {
        return req.cookies.market || 'en-US'
      }
    }
  }
}

Shorthand example:

Same example, written differently.

module.exports = {
  hooks: {
    serviceWorkerCacheKey: () => req => req.cookies.market || 'en-US'
  }
}

Register

Besides any config or lifecycle hooks your app or plugins may implement, the service worker itself will need to be registered for your app.

A registration script is generated automatically by the plugin, and made available to requests as req.swRegisterScript. You can use this when rendering the index.html for your app, or other server side rendering, ensuring the earliest registration of the service worker.

How it works

Because there should only be a single service worker registered per scope (or page), this plugin provides a lifecycle hook for apps and plugins to append their service worker code. This also allows content to be generated based on the request, such as language or cookie settings.

When a service worker request comes in, the Request object is passed through the registered cacheKey functions and a key string assembled. If the cache does not contain the assembled key, a new service worker is composed and placed in cache. If the cache does contain the key, the cached service worker content is returns and compose skipped.

How to test

As this plugin expects to compose a service worker scripts from multiple sources, testing can be a bit tricky.

The most straight-forward approach is to author unit tests for service workers partials. To do so, use the loaded script approach which will allow your tests to import the script also. Next, you will need to mock the service worker environment, which can be easily done using service-worker-mock.

License

MIT

7.0.0-next.21

21 hours ago

7.0.0-next.9

6 days ago

7.0.0-next.10

6 days ago

7.0.0-next.7

6 days ago

7.0.0-next.11

6 days ago

7.0.0-next.8

6 days ago

7.0.0-next.12

6 days ago

7.0.0-next.13

6 days ago

7.0.0-next.6

6 days ago

7.0.0-next.20

6 days ago

7.0.0-next.5

7 days ago

6.46.8

8 days ago

7.0.0-next.4

9 days ago

7.0.0-next.3

13 days ago

7.0.0-next.2

20 days ago

7.0.0-next.1

21 days ago

7.0.0-next.0

21 days ago

7.0.0-cli.7

1 month ago

7.0.0-cli.6

1 month ago

6.46.1-cli.0

2 months ago

7.0.0-cli.5

2 months ago

7.0.0-cli.4

2 months ago

7.0.0-cli.1

2 months ago

7.0.0-cli.0

2 months ago

7.0.0-cli.3

2 months ago

7.0.0-cli.2

2 months ago

6.46.3-cli.0

2 months ago

6.46.2

2 months ago

7.0.0-canary.1

2 months ago

6.46.2-esm.0

2 months ago

6.45.2

3 months ago

6.45.0

4 months ago

6.43.0

7 months ago

6.39.3

11 months ago

6.39.0

11 months ago

6.38.8

12 months ago

6.38.6

1 year ago

6.38.5

1 year ago

6.38.1

1 year ago

6.36.1

1 year ago

6.38.0

1 year ago

6.34.6

2 years ago

6.36.0

1 year ago

6.34.4

2 years ago

6.34.2

2 years ago

6.26.1

2 years ago

6.28.0

2 years ago

6.21.0

2 years ago

6.24.2

2 years ago

6.24.0

2 years ago

6.20.4

2 years ago

6.20.3

2 years ago

6.20.2

2 years ago

6.19.0

2 years ago

6.10.1

2 years ago

6.10.0

2 years ago

6.14.0

2 years ago

6.11.2

2 years ago

6.17.0

2 years ago

6.15.2

2 years ago

6.0.12

3 years ago

6.0.0

3 years ago

6.0.0-canary.13

3 years ago

6.0.0-canary.5

3 years ago

6.0.0-canary.2

4 years ago

6.0.0-canary.0

4 years ago

5.6.0

4 years ago

5.3.1

4 years ago

5.0.2

4 years ago

5.0.1

4 years ago

5.0.0

4 years ago

5.0.0-canary.4

4 years ago

5.0.0-canary.3

4 years ago

5.0.0-canary.2

4 years ago

5.0.0-canary.1

4 years ago

5.0.0-canary.0

4 years ago