Can anyone provide guidance on setting up a TypeScript service worker in Vue 3 using the vite-plugin-pwa extension?

I am looking to develop a single-page application that can be accessed offline. To achieve this, I have decided to implement a PWA Service Worker in my Vue webapp using TypeScript and Workbox. I found useful examples and guidance on how to do this at .

However, during the TypeScript build process, I encountered several TS2403 errors such as:

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! <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e5938c9180c895978a8f808691a5d5cbd5cbd5">[email protected]</a> build: `vue-tsc --noEmit && vite build`
npm ERR! Exit status 2

Below are the steps I followed:

Firstly, I installed the Vite plugin by running the command:

npm i vite-plugin-pwa -D

Then, in the vite.config.ts file, I made the following addition:

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

The initial build worked fine, but subsequent steps led to the aforementioned error.

Next, in the same vite.config.ts file, I added configuration for using TypeScript:

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

I then updated the tsconfig.json by including WebWorker in the lib array and adding types:

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

Finally, I created a new file sw.ts in the src folder with the following content:

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

declare const self: ServiceWorkerGlobalScope

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

Answer №1

To optimize your code, I suggest removing the inclusion of "WebWorker" from the tsconfig.json file's lib property. Instead, you can simply use the

/// <reference lib="webworker" />
triple-slash directive to specify the lib reference at the beginning of your sw.ts file.

If you need further guidance, take a look at this sample project demonstrating this approach.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error TS2322: The function expecting a type of 'FormEventHandler<HTMLFormElement>' cannot be assigned the type '(data: TicketFullDTO) => Promise<void>'

I am currently working on creating an edit form to modify data from a database based on its ID. Here is my approach: import React, {FormEvent, useEffect, useState} from "react"; import TextField from "@material-ui/core/TextField" ...

The assignment of `accessToken` is restricted in Mapbox-gl's typing

I'm currently utilizing the mapbox-gl library in conjunction with TypeScript. Moreover, I have successfully installed its type definitions that are sourced from the community using @types/mapbox-gl. However, when attempting to import and assign an acc ...

Ways to utilize multiple tsconfig files within VS Code

My project structure in Visual Studio Code is fairly common with a client, server, and shared directory setup: ├── client/ │ ├── tsconfig.json ├── shared/ ├── server/ │ ├── tsconfig.json ├── project.json The tw ...

What is the process for setting up custom global interfaces in TypeScript using .d.ts files?

I'm currently facing an issue in my ReactJS project using Webpack2 and TypeScript. Everything is functioning perfectly except for one thing - I've been struggling to move my self-written interfaces into separate files so they are accessible throu ...

Exporting several functions within a TypeScript package is advantageous for allowing greater flexibility

Currently, I am in the process of developing an npm package using Typescript that includes a variety of functions. Right now, all the functions are being imported into a file called index.ts and then re-exported immediately: import { functionA, functionB ...

List the attributes that have different values

One of the functions I currently have incorporates lodash to compare two objects and determine if they are identical. private checkForChanges(): boolean { if (_.isEqual(this.definitionDetails, this.originalDetails) === true) { return false; ...

Learn the best way to retrieve the highest number from a Array<String> in TypeScript or JavaScript

Can someone help me create a function in JS or TS that meets the following requirements? I am looking for a functional programming approach. ・Input type: Array(String) ・Output type: string or undefined Examples Input Result ["" ...

Can a TypeScript generator function be accurately typed with additional functionality?

Generator functions come with prototype properties that allow for the addition of behavior. The generated generators inherit this behavior. Unfortunately, TypeScript does not seem to recognize this feature, leaving me unsure of how to make it aware. For i ...

Custom Type Guard Leads to Intersection Type Outcome

Recently, I've been experimenting with Typescript and decided to explore the creation of an innovative Either type that could distinguish between success and failure scenarios. Utilizing a user-defined type guard, I managed to precisely narrow down th ...

Parse the local JSON file and convert it into an array that conforms to an

My goal is to extract data from a local JSON file and store it in an array of InputData type objects. The JSON contains multiple entries, each following the structure of InputData. I attempted to achieve this with the code snippet below. The issue arises ...

Sorting an array of objects in Typescript using a dynamic property name for generics

My goal is to develop a versatile, typed function that can arrange an array of objects by a numerical value housed under a dynamically named property within each object. Here is my current progress: export const sortByNumber = <T, K extends keyof T> ...

Utilizing Express, Request, and Node.js to manage GET requests in typescript

I'm struggling with using Express and Request in my project. Despite my efforts, the response body always returns as "undefined" when I try to get JSON data from the server. In my server.js file, this is the code snippet I have been working on: impo ...

What is the best way to trigger a function in React when a constant value is updated?

In my React application, I have 3 components. The parent component and two child components named EziSchedule and EziTransaction. Each component fetches its own data from an API. The data to display in the EziTransaction child component depends on the reco ...

TypeScript's HashSet Implementation

I'm working on a simple TypeScript task where I need to extract unique strings from a map, as discussed in this post. Here's the code snippet I'm using: let myData = new Array<string>(); for (let myObj of this.getAllData()) { let ...

Can a decorator be added to a Typescript class after it has been created?

Is it possible to update a class with inversify's @injectable decorator after it has been created? My use case involves using a mocking library like ts-auto-mock to generate a mock for me, and then applying the @injectable decorator to bind the mock t ...

I'm puzzled by the error message stating that '<MODULE>' is declared locally but not exported

I am currently working with a TypeScript file that exports a function for sending emails using AWS SES. //ses.tsx let sendEmail = (args: sendmailParamsType) => { let params = { //here I retrieve the parameters from args and proceed to send the e ...

You must use the 'new' keyword in order to invoke the class constructor

Although similar questions have been asked before, my situation differs from the typical scenarios. I have a basic base class named CObject structured as follows: export class CObject extends BaseObject { constructor() { super(); } sta ...

A Fresh Approach for Generating Unique UUIDs without Bitwise Operators

To generate UUIDs in TypeScript, I have implemented a method inspired by the solution provided on Stack Overflow. The code effectively converts JavaScript to TypeScript. generateUUID(): string { let date = new Date().getTime(); if (window.performa ...

Are you facing difficulties while trying to utilize useContext in your React application?

I have a basic React application where I need to implement useContext. (by the way, I am using Vite + React) Below is the code for my Context.jsx file: import React, {useContext} from 'react'; const emailContext = React.createContext(); expor ...

Creating a searchable and filterable singleSelect column in the MUI DataGrid: A step-by-step guide

After three days of working on this, I feel like I'm going in circles. My current task involves fetching data from two API sources (json files) using the useEffect hook and storing them in an array. This array contains a large number of products and a ...