I’m on vacation, trying to renew my personal website (that’s just a one-page showcase right now) before coming back to work. I’ve already replaced Webpack with Vite, since I think that it’s a better tool to date — but I still needed to turn it into a full Progressive Web Application.
PWA Vite Plugin
I know, PWA Vite Plugin is a great choice to do the same without headache, but I just wanted to have a simple Service Worker to cache the website assets and I didn’t want to add further development dependencies. If you got here, I think you’re trying to achieve something similar.
Then, I found an existing solution that was proposed about two years ago by @reeshee, but it lacks a TypeScript support that I need and it requires yet another dependency… so I tried to build my own. I succeeded in registering a Service Worker, but it needs lots of improvements.
I took inspiration by an old Workbox tutorial, although you don’t need it at all to follow my instructions below: remember, the main goal here is getting things done without plugins or development dependencies, so I won’t ask you to install any except Vite itself.
One of the flaws in my approach is that you need to add an inline script in your index.html
(that’s why @reeshee relied on register-service-worker
, I guess): I don’t see this as a security issue, but you could. Maybe using a nonce
global attribute can be useful here.
<script>
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(() => {
console.info('Service worker registered!');
}).catch((error) => {
console.warn(`Error registering service worker:\n${error}.`);
});
}
});
</script>
Above, a simplified version of the script proposed by the Google tutorial I already mentioned. Now it’s time to create an actual Service Worker: I chose to call it sw.js
, but you can choose whatever you want — just remember to keep the .js
extension here and to be consistent.
Yes, because I said that I want to use TypeScript, so the Service Worker sources will be saved somewhere in a .ts
file instead. I followed the conventions, creating a /src/ts/sw.ts
file in the same folder of the main app.ts
file which handles all PWA features.
Of course, following the Google guidelines, I chose to transpile and move it to the /dist
root along with index.html
to share the same scope. This was a bit challenging at first, and that’s where Rollup comes in handy: being a Vite implicit dependency, you don’t need to install it.
Rollup and TypeScript
I didn’t change anything in tsconfig.json
, even though mine is more “futuristic” than usual, but I found a solution to fix an error I’ve got on the Service Worker. This has nothing to do with the integration itself and I won’t share the sources here, because I think that adding logics to the sw.ts
file is up to you.
Anyway, the main changes belong to vite.config.ts
, where you should include the Rollup configuration and adapt the following example to your folder structure. I said that you should, because there’s the chance that you don’t want to strictly follow my instructions and you can do it without issues.
import type { UserConfig } from 'vite';
export default {
base: '/',
build: {
outDir: 'dist',
assetsDir: './',
emptyOutDir: true,
rollupOptions: {
input: {
index: 'index.html',
sw: 'src/ts/sw.ts',
},
},
},
} satisfies UserConfig;
Above, the rollupOptions
object is required, because otherwise Vite will skip the Service Worker transpiling: you must not import sw.ts
in your main TypeScript file, since this would break the whole logic. That’s why I needed to list index.html
here. It’s not mandatory.
If you noticed, I changed the assetsDir
too. I wanted to keep both the sw.js
and the index.html
output files in the root, then I opted for this solution, but it will move the main module and the styles there as well: in my actual integration I’ve also added further directives to avoid it.
Basically, I listed all the input files and set a custom output
object to rule their destination path. I chose to remove hashes, because my Service Worker doesn’t need them, but yours could: I can’t know how you handle your caches in advance, so I prefer to skip this part.
I plan to share my solution for it, as well as the whole Service Worker sources, once I’m 100% done. If you’re curious, you can always have a look at the GitHub repository of my personal website to get inspired: it’s a work in progress, so don’t expect everything to work.
Building this solution, I saw that Vite is going to replace Rollup with Rolldown and I gave it a try. Unfortunately, it still needs improvements in the way it handles CSS files, so I was forced to rollback to Rollup, but I think that I will come back to it when ready to be released into production.
Top comments (0)