vite.config.ts

3.1 KB · raw

1import { defineConfig } from "vite";2import solidPlugin from "vite-plugin-solid";3import { crx } from "@crxjs/vite-plugin";4import { copyFileSync, mkdirSync, readFileSync } 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"));10const passkeyE2E = process.env.PEACH_E2E_PASSKEYS === "1";11const outDir = target === "firefox" ? "dist-firefox" : "dist-chrome";1213// Copy the pdf.js worker into the build output so the popup can load it via14// chrome.runtime.getURL('pdf.worker.min.mjs'). The pdfjs-dist module's default15// workerSrc points inside node_modules, which is not reachable from a packaged16// extension — the worker file must sit alongside the rest of the assets.17const copyPdfJsWorker = {18  name: "copy-pdfjs-worker",19  closeBundle() {20    mkdirSync(outDir, { recursive: true });21    copyFileSync(22      resolve("node_modules/pdfjs-dist/build/pdf.worker.min.mjs"),23      resolve(outDir, "pdf.worker.min.mjs"),24    );25  },26};2728export default defineConfig({29  plugins: [30    solidPlugin(),31    crx({ manifest, browser: target === "firefox" ? "firefox" : "chrome" }),32    copyPdfJsWorker,33  ],34  base: "./",35  define: {36    __PEACH_E2E_PASSKEYS__: JSON.stringify(passkeyE2E),37  },38  build: {39    outDir,40    // emptyOutDir must stay false. When true, Vite tries to remove the41    // contents of the outDir before each build, which throws EPERM on FUSE42    // and some mounted filesystems and aborts the whole build. Overwriting43    // in place works everywhere.44    emptyOutDir: false,45    // The MV3 service worker has no `document`. Vite's module-preload helper46    // injects <link rel=modulepreload> via document.getElementsByTagName, and47    // it runs synchronously inside every dynamic import() that carries chunk48    // deps. In the worker that throws `ReferenceError: document is not defined`49    // synchronously — escaping the import's own .catch() and tearing down the50    // caller (e.g. passkey-get persisting signCount via fireSyncTrigger).51    // Disabling preload makes the helper a no-op; the link hints are only a52    // page-load micro-optimisation and the popup loads fine without them.53    modulePreload: false,54    target: "esnext",55    rollupOptions: {56      // HV-2: the offscreen document (Chrome only — Firefox has no57      // chrome.offscreen) must be bundled and emitted so the background can58      // load it via chrome.offscreen.createDocument. Firefox capability-checks59      // chrome.offscreen and never references it.60      input:61        target === "firefox"62          ? undefined63          : { offscreen: resolve("src/background/offscreen.html") },64      output: {65        manualChunks(id) {66          if (id.includes("node_modules/solid-js")) return "vendor-solid";67          if (id.includes("node_modules/otpauth")) return "vendor-otp";68          if (id.includes("node_modules/papaparse")) return "vendor-parse";69          if (id.includes("node_modules/qrcode")) return "vendor-qr";70        },71      },72    },73  },74});