Celdus
Celdus

Reputation: 2110

How do I implement a typescript service worker with vite-plugin-pwa in Vue 3

I want to make a single-page application available for offline. So I want to use a PWA Service Worker in my Vue webapp and use typescript and workbox for it. I followed the examples from https://vite-plugin-pwa.netlify.app/guide/inject-manifest.html#typescript-support.

When building the typescript I get many TS2403 errors like:

node_modules/typescript/lib/lib.webworker.d.ts:5720:13 - error TS2403: Subsequent variable declarations must have the same type.  Variable 'onoffline' must be of type '((this: Window, ev: Event) => any) | null', but here has type '((this: DedicatedWorkerGlobalScope, ev: Event) => any) | null'.
// ...
Found 21 errors in 2 files.

Errors  Files
     3  node_modules/typescript/lib/lib.dom.d.ts:25
    18  node_modules/typescript/lib/lib.webworker.d.ts:25
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: `vue-tsc --noEmit && vite build`
npm ERR! Exit status 2

Here are the steps I did.

The first thing I did was to install the Vite plugin:

npm i vite-plugin-pwa -D

then to the vite.config.ts I added the

import { VitePWA } from "vite-plugin-pwa";
//...
VitePWA({
    strategies: 'generateSW', // default
    includeAssets: [ "favicon.svg", /* ... */ ],
    manifest: {
      name: "Name of your app", 
      // ...
    },
}),
// ...

First build here was working fine, but with the next steps I get the error.

Now in the vite.config.ts I added the config for using a typescript

VitePWA({
    srcDir: 'src',
    filename: 'sw.ts',
    workbox: { 
        swDest: "sw.js"
    },
    strategies: 'injectManifest', // changed
    // ...

then changed the tsconfig.json (added WebWorker to lib and added types):

//"lib": ["esnext", "dom" ], // before
"lib": ["esnext", "dom", "WebWorker"],
"types": ["vite-plugin-pwa/client"]

and finally added the sw.ts in the src folder:

/// <reference lib="WebWorker" />
import { skipWaiting, clientsClaim } from "workbox-core"
import { precacheAndRoute } from "workbox-precaching";

declare const self: ServiceWorkerGlobalScope

precacheAndRoute(self.__WB_MANIFEST);
skipWaiting();
clientsClaim();

Upvotes: 12

Views: 14804

Answers (1)

Jeff Posnick
Jeff Posnick

Reputation: 56144

I would recommend removing "WebWorker" from your tsconfig.json's lib property, and just use the /// <reference lib="webworker" /> triple-slash directive to add the lib reference at the top of your sw.ts file.

You can see an example project with this setup if it helps.

Upvotes: 4

Related Questions