123456789101112131415import { readFileSync, existsSync, readdirSync } from "fs";16import { join, dirname } from "path";17181920const DISTS = ["dist-chrome"];2122const STATIC_IMPORT = /(?:^|[;\s})])(?:import|export)\s*(?:[^`"'()]*?from\s*)?[`"']([^`"']+)[`"']/g;23const DYNAMIC_IMPORT = /import\(\s*[`"']([^`"']+)[`"']\s*\)/g;2425function matches(source, re) {26 return [...source.matchAll(re)].map((m) => m[1]);27}2829function resolveFrom(fromFile, spec) {30 if (!spec.startsWith(".")) return null;31 return join(dirname(fromFile), spec);32}333435function serviceWorkerEntry(dist) {36 const loader = join(dist, "service-worker-loader.js");37 if (existsSync(loader)) {38 const [spec] = matches(readFileSync(loader, "utf8"), STATIC_IMPORT);39 if (spec) return resolveFrom(loader, spec);40 }41 const manifest = JSON.parse(readFileSync(join(dist, "manifest.json"), "utf8"));42 const direct = manifest.background?.service_worker;43 return direct ? join(dist, direct) : null;44}4546function walk(entry) {47 const seen = new Set();48 const violations = [];49 const stack = [entry];50 while (stack.length) {51 const file = stack.pop();52 if (seen.has(file) || !existsSync(file)) continue;53 seen.add(file);54 const source = readFileSync(file, "utf8");55 for (const spec of matches(source, STATIC_IMPORT)) {56 const next = resolveFrom(file, spec);57 if (next) stack.push(next);58 }59 for (const spec of matches(source, DYNAMIC_IMPORT)) {60 violations.push({ file, spec });61 }62 }63 return { chunks: seen.size, violations };64}6566let failed = false;67for (const dist of DISTS) {68 if (!existsSync(dist)) {69 console.error(`FAIL: ${dist} not built — nothing to check`);70 failed = true;71 continue;72 }73 const entry = serviceWorkerEntry(dist);74 if (!entry || !existsSync(entry)) {75 console.error(`FAIL ${dist}: could not locate the service worker entry`);76 failed = true;77 continue;78 }79 const { chunks, violations } = walk(entry);80 if (violations.length) {81 failed = true;82 console.error(`FAIL ${dist}: runtime import() in the service worker graph`);83 for (const v of violations) console.error(` ${v.file} -> import("${v.spec}")`);84 console.error(85 " Fix: make these static top-level imports. Dynamic import() cannot run in a service worker.",86 );87 } else {88 console.log(`ok ${dist}: ${chunks} worker chunks, no runtime import()`);89 }90}9192process.exit(failed ? 1 : 0);