vite.config.ts

3.5 KB · raw

1import { defineConfig } from "vite";2import solidPlugin from "vite-plugin-solid";3import { crx } from "@crxjs/vite-plugin";4import { copyFileSync, mkdirSync, readFileSync, writeFileSync } from "fs";5import { resolve } from "path";67const target = process.env.BUILD_TARGET || "chrome";8const manifestPath = target === "firefox" ? "./manifest.firefox.json" : "./manifest.json";9const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));10if (target === "chrome") {11  manifest.web_accessible_resources = [{12    matches: ["<all_urls>"],13    resources: ["<dynamic_resource>"],14  }];15}16const passkeyE2E = process.env.PEACH_E2E_PASSKEYS === "1";17const outDir = target === "firefox" ? "dist-firefox" : "dist-chrome";1819// Copy the pdf.js worker into the build output so the popup can load it via20// chrome.runtime.getURL('pdf.worker.min.mjs'). The pdfjs-dist module's default21// workerSrc points inside node_modules, which is not reachable from a packaged22// extension — the worker file must sit alongside the rest of the assets.23const copyPdfJsWorker = {24  name: "copy-pdfjs-worker",25  closeBundle() {26    mkdirSync(outDir, { recursive: true });27    copyFileSync(28      resolve("node_modules/pdfjs-dist/build/pdf.worker.min.mjs"),29      resolve(outDir, "pdf.worker.min.mjs"),30    );31    if (target === "chrome") {32      const outputManifest = resolve(outDir, "manifest.json");33      const builtManifest = JSON.parse(readFileSync(outputManifest, "utf8"));34      writeFileSync(outputManifest, `${JSON.stringify(builtManifest, null, 2)}\n`);35    }36  },37};3839export default defineConfig({40  plugins: [41    solidPlugin(),42    crx({ manifest, browser: target === "firefox" ? "firefox" : "chrome" }),43    copyPdfJsWorker,44  ],45  base: "./",46  define: {47    __PEACH_E2E_PASSKEYS__: JSON.stringify(passkeyE2E),48    __PEACH_DEBUG__: false,49  },50  build: {51    outDir,52    // emptyOutDir must stay false. When true, Vite tries to remove the53    // contents of the outDir before each build, which throws EPERM on FUSE54    // and some mounted filesystems and aborts the whole build. Overwriting55    // in place works everywhere.56    emptyOutDir: false,57    // The MV3 service worker has no `document`. Vite's module-preload helper58    // injects <link rel=modulepreload> via document.getElementsByTagName, and59    // it runs synchronously inside every dynamic import() that carries chunk60    // deps. In the worker that throws `ReferenceError: document is not defined`61    // synchronously — escaping the import's own .catch() and tearing down the62    // caller (e.g. passkey-get persisting signCount via fireSyncTrigger).63    // Disabling preload makes the helper a no-op; the link hints are only a64    // page-load micro-optimisation and the popup loads fine without them.65    modulePreload: false,66    target: "esnext",67    rollupOptions: {68      // HV-2: the offscreen document (Chrome only — Firefox has no69      // chrome.offscreen) must be bundled and emitted so the background can70      // load it via chrome.offscreen.createDocument. Firefox capability-checks71      // chrome.offscreen and never references it.72      input:73        target === "firefox"74          ? undefined75          : { offscreen: resolve("src/background/offscreen.html") },76      output: {77        manualChunks(id) {78          if (id.includes("node_modules/solid-js")) return "vendor-solid";79          if (id.includes("node_modules/otpauth")) return "vendor-otp";80          if (id.includes("node_modules/papaparse")) return "vendor-parse";81        },82      },83    },84  },85});