93 lines
2.9 KiB
TypeScript
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,
|
|
),
|
|
},
|
|
});
|