Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a custom service worker events in vue-cli with typescript

I have a Vue-cli project with and want to enable offline support (pwa, progressive web app functionality). Therefore I installed the PWA-Plugin for the vue cli.

In the vue.config.js I configured the Pwa and the workbox like following:

...
pwa: {
    name: 'projectname',
    // configure the workbox plugin
    // workboxPluginMode: 'GenerateSW',
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      // swSrc is required in InjectManifest mode.
      swSrc: 'src/service-worker.js',
      }
}
...

Now I want to inject my following additional events into the service-worker (from src/service-worker.js)

self.addEventListener('push', function (event) {
    console.log('[Service Worker] Push Received.');
    console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
});

self.addEventListener('fetch', function (event) {
    console.log(event.request.url);
    // event.respondWith(() => {
    //     fetch(event.request)
    // }
    // );
});

In the registerServiceWorker.ts I commented the environment-check so the service-worker is also served on my localhost.

/* eslint-disable no-console */
import { register } from 'register-service-worker'
// if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n'
      )
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
// }

But when I check the service-worker.js which is served to the browser I only see the default service-worker

/* eslint-disable-next-line no-redeclare */
/* global self */

// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.

// It is read and returned by a dev server middleware that is only loaded
// during development.

// In the production build, this file is replaced with an actual service worker
// file that will precache your site's local assets.

self.addEventListener('install', () => self.skipWaiting())

self.addEventListener('activate', () => {
  self.clients.matchAll({ type: 'window' }).then(windowClients => {
    for (const windowClient of windowClients) {
      // Force open pages to refresh, so that they have a chance to load the
      // fresh navigation response from the local dev server.
      windowClient.navigate(windowClient.url)
    }
  })
})

I would expect it would look like:

self.addEventListener('install', () => self.skipWaiting())
self.addEventListener('activate', () => {
  self.clients.matchAll({ type: 'window' }).then(windowClients => {
    for (const windowClient of windowClients) {
      // Force open pages to refresh, so that they have a chance to load the
      // fresh navigation response from the local dev server.
      windowClient.navigate(windowClient.url)
    }
  })
})
self.addEventListener('push', function (event) {
    console.log('[Service Worker] Push Received.');
    console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
});
self.addEventListener('fetch', function (event) {
    console.log(event.request.url);
});

Further things I tried:

  • using src/service-worker.ts instead of a js file does not help.
  • using "vue-cli-service serve --mode production" also returns the false service worker.
  • when I put my additional code in the public folder and manually register the service worker I got the "push"-test to work, but the offline-caching obviously did not work.
like image 982
Celdus Avatar asked Apr 16 '20 19:04

Celdus


People also ask

Does vue2 support TypeScript?

You should also be familiar with Vue, vue-loader, and webpack. Vue 2 already has good support for TypeScript, and the recently published Vue 2.7 backported a lot of useful features from Vue 3, like composition API, <script setup> , and defineComponent , further improving the developer experience of TypeScript in Vue.

Does TypeScript work with Vue?

Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.

Does Vue 3 support TypeScript?

Now, you should be able to get your Vue app up and running in TypeScript with features like defineComponent , data, props, computed properties, methods, and watchers. Vue 3.0 includes better support for TypeScript out of the box, and the entire Vue code was rewritten in TypeScript to improve maintainability.

Does Vue CLI service use webpack?

It is the standard tooling baseline for using Vue JS which provides you with the Vue CLI service which is a runtime dependency, built on Webpack with 0 configs. It has a very extensive collection of plugins you can add to your project with a line of command.


1 Answers

First thing I had to do was add "devserver" to vue.config.js:

  devServer: {    
    https: true,
  },
  pwa: {
    // configure the workbox plugin
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      swSrc: 'src/service-worker.js',
      swDest: 'service-worker.js',
    }
  }
...

Further I did not manage to run the vue-cli service without Certificate-Error and serving the production environment (even though I build via production mode, with the correct service worker in the /dist folder).

My current workaround is using a .NetCore application where I copy the code to wwwroot and then run the solution with IISExpress. I use the npm run ship.

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "copydist": "xcopy .\\dist ..\\wwwroot\\ /s /y",
    "ship": "npm run build && npm run copydist",
    "test": "set NODE_ENV=production && npm run build && serve -s dist"
  },

Things I still haven't figured out are:

  • How I can use typescript for the serviceworker.
  • How to avoid the .NetCore workaround with a valid localhost cert.
like image 73
Celdus Avatar answered Oct 12 '22 16:10

Celdus