vite-pwa / vite-plugin-pwa

Zero-config PWA for Vite
https://vite-pwa-org.netlify.app/
MIT License
3.04k stars 200 forks source link

using custom SW in dev mode #475

Closed tmountjr closed 1 year ago

tmountjr commented 1 year ago

Is it possible to have a custom service worker running while in dev mode? My current setup uses a custom SW at /sw/service-worker.js, and a custom registration script at /src/registerServiceWorker.js:

import { registerSW } from "virtual:pwa-register";

if ("serviceWorker" in navigator) {
  registerSW({
    onRegisteredSW: (url) => {
      console.log(`Registered at url ${url}`);
    },
  });
}

My vite.config.ts looks like:

import { VitePWA, type VitePWAOptions } from "vite-plugin-pwa";

const pwaOptions: Partial<VitePWAOptions> = {
  devOptions: {
    enabled: true,
  },
  srcDir: "sw",
  filename: "service-worker.js",
  injectRegister: null,
};

...

export default defineConfig({
  plugins: [vue(), VitePWA(pwaOptions)],
...

(Should point out I'm using Vue, if it matters.)

In /src/main.ts I'm simply importing the SW registration file (import './registerServiceWorker.js') as Vue starts up.

This all works great when I do a build and run that build - I can see my custom SW (which includes some code that's easily searchable even in the minified version, so I know the right service worker is being loaded). But when I am in dev mode via yarn dev the service worker is the default dev-sw.js file. This makes it hard to develop my site with the SW functionality without having to stop and rebuild my project after every change. Is there a way to force the path of the dev service worker rather than use the one that the plugin builds?

tmountjr commented 1 year ago

Example repo at https://github.com/tmountjr/edgio-vue3

userquin commented 1 year ago

https://vite-pwa-org.netlify.app/guide/inject-manifest.html

tmountjr commented 1 year ago

Right, I had that set up in the repo with no apparent effect (but I just pushed my example to include them this time) - despite setting the filename to service-worker.js and the source directory to src (which all works fine when built), the plugin is still trying to load dev-sw.js which doesn't exist and is causing a 404 when the site loads.

Screenshot 2023-02-23 at 18 40 35
userquin commented 1 year ago

@tmountjr the library you're using is not compatible using classic or module, you've 2 options: 1) remove @edgio/prefetch from your custom sw 2) use type: 'classic' and use importScripts also in your custom sw, you will also need to add rollup and esbuild polyfills in Vite configuration

Adding process polyfills, I get this error:

imagen

tmountjr commented 1 year ago

Thanks for looking into it. We may have to skip using this plugin if the polyfill approach doesn't work out - dropping the framework's package isn't really an option.

Out of curiosity, what would make our library compatible with either classic or module?

userquin commented 1 year ago

Out of curiosity, what would make our library compatible with either classic or module?

Provide 2 versions, one using importScripts (current one) and another using ESM like you're using in your custom SW.

I suggest you to remove only the imports from the custom sw not from the app.

userquin commented 1 year ago

@tmountjr if @edgio/prefetch is your library, you can create one for Vite, you only need to replace process.env.EDGIO_** with import.meta.env.VITE_EDGIO_** using static imports (instead importScripts).

You'll need to provide it with "type": "module" adding exports entry with dts and js module.

If you have public repo maybe I can take a look...

tmountjr commented 1 year ago

I don't know if the source is public or not - I imagine it isn't because we're probably doing something proprietary in there. But I'll check with the devX team - it turns out that our prefetching component (which is the primary use case for our service worker) has its own installation/registration method (I think it uses rollup on the backend to compile the SW and move it into the dist folder), but there might be some benefits to tweaking things to work on a wider variety of setups, especially once you move past Vue and into other platforms.

In the meantime, I'll go ahead and close this since we have a working solution (updated the above repo and I'll keep it around for reference) and some leads on how to make it compatible here. Thanks for taking a look!