Skip to content

Styleguide

Matt Gaunt edited this page Dec 12, 2017 · 1 revision

This page outlines any generic rules that the Workbox project is adhering to in terms of its implementation and its API.

Positional and Destructured Arguments

Methods

For methods called against a Workbox module, we will use positional arguments.

🎉 Good

router.registerRoutes([...]);

☠️ Bad

router.registerRoutes({routes: [....]});

Reasoning

  • Avoids verbose code

Exemptions

  • If you are expecting a wide variety of optional values, having an options object makes more sense. But required fields should be positional.
    new Route(matchFunc, handleFunc, options);

Callbacks

If we are calling a callback (i.e. calling out of a Workbox module), we will use destructuring.

🎉 Good

plugin.cacheDidUpdate({cacheName, request, cachedResponse, newResponse});

☠️ Bad

router.cacheDidUpdate(cacheName, request, cachesRedponse, newResponse);

Reasoning

  • Developers can select just the elements they care about
    plugin.cacheDidUpdate({cachedResponse})
  • Useful for developers learning about the api
    {
        cacheDidUpdate: (values) => console.log(values),
    }

Service Worker Event Listeners

Whenever one of our modules registers an event listener, we are blocking developers from being able to use modules in their own codes execution flow. This is a subtle problem that is easy to over look.

To overcome this, our styleguide dictates that no service worker events should be registered in the classes of a module and must only be registered in the default export of a module.

This means that: 1.) We are forced to make it possible for developers to use our lower level classes as we are doing it ourselves in the default export. 2.) We are forced to make sane API's to work with events.

Plugins in SW

🎉 Good

class SomeClassPlugin {
  constructor(arg1, arg2) {
    this._someInstance = new SomeClass(arg1, arg2);
  }
 
  ...
}

☠️ Bad

class SomeClassPlugin extends SomeClass {
  ...
}

Reasoning Modules that provide a standalone class and plugin should not have the plugin extend the standalone class.

This way, should any method in the standalone class have the same name as a lifecycle callback, it won't be inadvertently used when it's exposed via the Plugin. Plus it keeps the API surface of the plugin clean.