/** * Vite config for the Chrome extension. * Builds the extension into dist/ for loading as an unpacked extension. * * Usage: * npm run dev — watch mode, rebuild on change * npm run build — production build */ import { defineConfig } from 'vite'; import { resolve } from 'path'; import { copyFileSync, mkdirSync, writeFileSync } from 'fs'; import sharp from 'sharp'; export default defineConfig({ root: 'src', plugins: [ { name: 'generate-icons', async generateBundle() { const outDir = resolve(__dirname, 'dist'); mkdirSync(resolve(outDir, 'icons'), { recursive: true }); const sizes = [16, 48, 128]; const svgPath = resolve(__dirname, 'src/icons/icon.svg'); const outDirs = [ resolve(outDir, 'icons'), resolve(__dirname, 'icons'), ]; for (const size of sizes) { const buffer = await sharp(svgPath) .resize(size, size) .png() .toBuffer(); for (const dir of outDirs) { mkdirSync(dir, { recursive: true }); writeFileSync(resolve(dir, `icon${size}.png`), buffer); } } }, }, { name: 'copy-manifest', generateBundle() { const manifestPath = resolve(__dirname, 'manifest.json'); const outPath = resolve(__dirname, 'dist/manifest.json'); copyFileSync(manifestPath, outPath); }, }, ], build: { outDir: '../dist', emptyOutDir: true, rollupOptions: { input: { background: resolve(__dirname, 'src/background/background.js'), content: resolve(__dirname, 'src/content/content.js'), viewer: resolve(__dirname, 'src/viewer/viewer.html'), viewerIndex: resolve(__dirname, 'src/viewer/index.html'), }, output: { entryFileNames: '[name].js', chunkFileNames: 'chunks/[name].js', assetFileNames: '[name][extname]', }, }, }, });