Files
clean-architecture-frontend…/vite.service-worker.config.ts
T
2026-08-01 19:39:59 +09:00

93 lines
2.9 KiB
TypeScript

import { readFile } from "node:fs/promises";
import { defineConfig } from "vite";
import {
SERVICE_WORKER_CACHE_SCHEMA_VERSION,
SERVICE_WORKER_PROTOCOL_VERSION,
SERVICE_WORKER_SCRIPT_PATH,
} from "./src/contracts/service-worker.ts";
import { INSTALLED_RUNTIME_CAPABILITIES } from "./src/features/installed-runtime-capabilities.ts";
import { resolveServiceWorkerBuildInput } from "./scripts/lib/service-worker-build-input.ts";
/**
* §17.2.2 step 5. The Service Worker build.
*
* Runs only when the static selection is `ACTIVE`, after the app build has
* completed and the hashed asset list has been generated. `emptyOutDir` is
* false so it adds `service-worker.js` beside the already-built app rather than
* replacing it.
*/
const selection = INSTALLED_RUNTIME_CAPABILITIES.serviceWorker;
async function readGenerated<T>(path: string, exportName: string): Promise<T> {
try {
const module = (await import(path)) as Record<string, unknown>;
if (!(exportName in module)) {
throw new TypeError(`Generated module does not export ${exportName}.`);
}
return module[exportName] as T;
} catch (error) {
throw new TypeError(`Required generated module is unavailable: ${path}`, {
cause: error,
});
}
}
const assets = await readGenerated(
"./.generated/frontend-runtime/service-worker-assets.ts",
"SERVICE_WORKER_ASSETS",
);
const contractSet = await readGenerated<{ setDigest?: string }>(
"./.generated/frontend-runtime/contract-set.ts",
"BUILD_CONTRACT_SET",
);
const runtimeConfig = JSON.parse(
await readFile("public/config.json", "utf8"),
) as Record<string, string>;
const buildId = process.env.VITE_BUILD_ID ?? "local-build";
const releaseId = process.env.RELEASE_ID ?? "local-release";
const buildInput = resolveServiceWorkerBuildInput({
selection,
assets,
contractSet,
runtimeConfig,
buildId,
releaseId,
});
export default defineConfig({
build: {
// §17.2.2: exactly one input, exactly one output, no additional chunk.
emptyOutDir: false,
sourcemap: false,
rollupOptions: {
input: "src/adapters/service-worker/service-worker-entry.ts",
output: {
format: "es",
inlineDynamicImports: true,
entryFileNames: SERVICE_WORKER_SCRIPT_PATH,
},
},
},
define: {
__CA_SERVICE_WORKER_BUILD_INFO__: JSON.stringify({
serviceWorkerProtocolVersion: SERVICE_WORKER_PROTOCOL_VERSION,
cacheSchemaVersion: SERVICE_WORKER_CACHE_SCHEMA_VERSION,
buildId,
releaseId,
contractSetDigest: buildInput.contractSetDigest,
staticAssetSetDigest: buildInput.assets.setDigest,
}),
__CA_SERVICE_WORKER_ASSETS__: JSON.stringify(buildInput.assets),
__CA_SERVICE_WORKER_HANDLERS__: JSON.stringify(buildInput.handlers),
__CA_RUNTIME_CONFIG_URL__: JSON.stringify(
process.env.VITE_RUNTIME_CONFIG_URL ?? "/config.json",
),
__CA_RELEASE_MANIFEST_URL__: JSON.stringify(
buildInput.releaseManifestUrl,
),
},
});