I am using service worker for my project. For some time I did not need code-splitting and the web app was working offline without extra configuration, but now I need to tell the service worker about my assets (paths and names of different chunks) for it to handle it in background while the network is available.
To build a service worker file I assembled custom Vite plugin like this:
import * as child from "child_process";
import { build } from "esbuild";
import { replace } from "esbuild-plugin-replace";
import { join } from "node:path";
import type { PluginOption } from "vite";
/**
* Returns the hash of the latest git commit
*/
export function getCommitHash(short = false) {
return child
.execSync(`git rev-parse ${short ? "--short" : ""} HEAD`)
.toString()
.trim();
}
export const compileServiceWorker: PluginOption = {
apply: "build",
enforce: "post",
name: "compile-service-worker",
transformIndexHtml() {
void build({
bundle: true,
entryPoints: [ join(process.cwd(), "src", "service-worker.js") ],
minify: true,
outfile: join(process.cwd(), "dist", "service-worker.js"),
plugins: [
replace({
values: {
"__COMMIT_HASH__": () => getCommitHash()
}
})
],
target: "es2021"
});
}
};
Here I minify the service worker and put some sort of hash based on latest commit for service worker to update.
I can write up some script that will get all assets paths and names after build, but I feel there is a better way of doing it via Vite itself. Can somebody point me to some direction?
I am aware of the vite-pwa
plugin, but I want to do this myself and learn how to do it.
I have the example of something similar in squoosh
app here, but that project is built using Rollup.
I found a solution for my problem.
There is a hook generateBundle
, here the generated bundle information as an object is passed via bundle
argument:
generateBundle(this, options, bundle) {
console.log(Object.keys(bundle));
}