vue-storefront
Version:
A Vue.js, PWA eCommerce frontend
61 lines (44 loc) • 2.78 kB
Markdown
# Introduction
We're using service workers for two main purposes:
1. To cache out static and dynamic data feeds - to make tham available offline (https://developers.google.com/web/fundamentals/primers/service-workers/)
2. To run offline data sync using service workers
To achieve the 1. we're using sw-precache from Google (https://github.com/GoogleChromeLabs/sw-precache) and for the second - Vanila JS with a little help from sw-toolbox (https://www.google.pl/search?q=sw-toolbox&oq=sw-toolbox&aqs=chrome..69i57j69i60l3j0l2.1529j0j4&sourceid=chrome&ie=UTF-8)
# Making things happen
The service-worker source code for vue-storefront is pre-compiled with Babel presets and all is stored in additional theme-specific Service WOrker in `src/{themename}/service-worker-ext.js` which file is attached to `service-worker.js` generated by sw-toolbox.
After changing anything to `service-worker-ext.js`, despite you're in `npm run dev` auto reloading mode, you need to do two things:
1. Recompile app (which regenerates service-worker):
`npm run build`
2. Reload Service worker in Dev Tools (in Chrome - just click "Unregister" and reload the page, new SW will be installed).
[How to work with service-workers in Chrome](chrome-dev-console.png)
# Communication with the app
Application can speak to service worker using the event bus - and only doing so. Please take a look at `/core/lib/sw.js` where we have following method:
```js
export function postMessage (payload) {
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) { // check if it's properly installed
navigator.serviceWorker.controller.postMessage(payload)
return false
} else { // no service workers supported push the queue manualy
return true
}
}
```
It allows you to send data to service worker. For example, when the order is placed (`/core/store/modules/checkout`):
```js
/**
* Add order to sync. queue
* @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md
*/
[types.CHECKOUT_PLACE_ORDER] (state, order) {
const ordersCollection = global.db.ordersCollection
const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough
order.id = orderId.toString()
order.transmited = false
order.created_at = new Date()
order.updated_at = new Date()
ordersCollection.setItem(orderId.toString(), order).catch((reason) => {
console.error(reason) // it doesn't work on SSR
sw.postMessage({ config: config, command: types.CHECKOUT_PROCESS_QUEUE }) // process checkout queue
console.info('Order placed, orderId = ' + orderId)
}) // populate cache
},
```