From 7b48b3a4d8793a70d0ba3b489451bc4485669e85 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Sat, 24 Jan 2026 00:09:50 +0000 Subject: [PATCH] fix(vite.config): enhance build process for Chrome, Firefox, and Safari extensions --- vite.config.mjs | 152 ++++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 70 deletions(-) diff --git a/vite.config.mjs b/vite.config.mjs index 0044f6dd..b2e3d8f9 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -1,3 +1,21 @@ +/** + * Vite Configuration for Mue Browser Extension + * + * This configuration handles building the extension for multiple browsers: + * - Chrome/Edge (Manifest V3) + * - Firefox (Manifest V3) + * - Safari (via Xcode project) + * + * Build Process: + * 1. Vite bundles the React app into /dist + * 2. Assets are copied to dist/src/assets for proper path resolution + * 3. Browser-specific builds are created in /build/{browser} + * 4. Distribution .zip files are generated for Chrome and Firefox + * + * Build Commands: + * - `bun run build` - Production build for all browsers + * - `bun run dev` - Development server with HMR + */ import { defineConfig, loadEnv } from 'vite'; import react from '@vitejs/plugin-react-swc'; import path from 'path'; @@ -12,101 +30,98 @@ const prepareBuilds = () => ({ name: 'prepareBuilds', buildEnd() { if (isProd) { - // make directories if not exist + console.log('📦 Building extension packages...'); + + // Ensure base directories exist fs.mkdirSync(path.resolve(__dirname, './build'), { recursive: true }); fs.mkdirSync(path.resolve(__dirname, './dist'), { recursive: true }); - // chrome - fs.mkdirSync(path.resolve(__dirname, './build/chrome'), { recursive: true }); + // Copy assets to dist for proper bundling + const distAssetsPath = path.resolve(__dirname, './dist/src/assets'); + fs.mkdirSync(distAssetsPath, { recursive: true }); + fs.cpSync(path.resolve(__dirname, './src/assets'), distAssetsPath, { recursive: true }); + + // Chrome Build + console.log('🔨 Building Chrome extension...'); + const chromeBuildPath = path.resolve(__dirname, './build/chrome'); + fs.mkdirSync(chromeBuildPath, { recursive: true }); + + // Copy manifest and background script fs.copyFileSync( path.resolve(__dirname, './manifest/chrome.json'), - path.resolve(__dirname, './build/chrome/manifest.json'), + path.resolve(chromeBuildPath, 'manifest.json'), ); fs.copyFileSync( path.resolve(__dirname, './manifest/background.js'), - path.resolve(__dirname, './build/chrome/background.js'), + path.resolve(chromeBuildPath, 'background.js'), ); + + // Copy locales fs.cpSync( path.resolve(__dirname, './manifest/_locales'), - path.resolve(__dirname, './build/chrome/_locales'), - { recursive: true }, - ); - fs.cpSync(path.resolve(__dirname, './dist'), path.resolve(__dirname, './build/chrome/'), { - recursive: true, - }); - fs.cpSync( - path.resolve(__dirname, './src/assets/icons'), - path.resolve(__dirname, './build/chrome/icons'), - { recursive: true }, - ); - fs.mkdirSync(path.resolve(__dirname, './build/chrome/src/assets'), { recursive: true }); - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(__dirname, './build/chrome/src/assets'), + path.resolve(chromeBuildPath, '_locales'), { recursive: true }, ); - // firefox - fs.mkdirSync(path.resolve(__dirname, './build/firefox'), { recursive: true }); + // Copy dist (bundled app) + fs.cpSync(path.resolve(__dirname, './dist'), chromeBuildPath, { recursive: true }); + + // Copy extension icons (separate from bundled assets) + fs.cpSync( + path.resolve(__dirname, './src/assets/icons'), + path.resolve(chromeBuildPath, 'icons'), + { recursive: true }, + ); + + // Firefox Build + console.log('🦊 Building Firefox extension...'); + const firefoxBuildPath = path.resolve(__dirname, './build/firefox'); + fs.mkdirSync(firefoxBuildPath, { recursive: true }); + + // Copy manifest and background script fs.copyFileSync( path.resolve(__dirname, './manifest/firefox.json'), - path.resolve(__dirname, './build/firefox/manifest.json'), + path.resolve(firefoxBuildPath, 'manifest.json'), ); fs.copyFileSync( path.resolve(__dirname, './manifest/background.js'), - path.resolve(__dirname, './build/firefox/background.js'), + path.resolve(firefoxBuildPath, 'background.js'), ); - fs.cpSync(path.resolve(__dirname, './dist'), path.resolve(__dirname, './build/firefox/'), { - recursive: true, - }); + + // Copy dist (bundled app) + fs.cpSync(path.resolve(__dirname, './dist'), firefoxBuildPath, { recursive: true }); + + // Copy extension icons (separate from bundled assets) fs.cpSync( path.resolve(__dirname, './src/assets/icons'), - path.resolve(__dirname, './build/firefox/icons'), - { recursive: true }, - ); - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(__dirname, './build/firefox/src/assets'), + path.resolve(firefoxBuildPath, 'icons'), { recursive: true }, ); - // safari + // Safari Build + console.log('🧭 Building Safari extension...'); const safariResourcesPath = path.resolve(__dirname, './safari/Mue Extension/Resources'); fs.mkdirSync(safariResourcesPath, { recursive: true }); - - // Copy manifest (already exists in Resources, but ensure it's updated) - // The manifest.json is managed separately for Safari - - // Copy background.js + + // Copy background script fs.copyFileSync( path.resolve(__dirname, './manifest/background.js'), path.resolve(safariResourcesPath, 'background.js'), ); - - // Copy built files from dist + + // Copy built files from dist (excluding manifest.json which Safari manages separately) fs.cpSync(path.resolve(__dirname, './dist'), safariResourcesPath, { recursive: true, - filter: (src) => { - // Don't overwrite the manifest.json we've already set up - return !src.endsWith('manifest.json'); - }, + filter: (src) => !src.endsWith('manifest.json'), }); - - // Copy icons + + // Copy extension icons fs.cpSync( path.resolve(__dirname, './src/assets/icons'), path.resolve(safariResourcesPath, 'icons'), { recursive: true }, ); - - // Copy src/assets - fs.mkdirSync(path.resolve(safariResourcesPath, 'src/assets'), { recursive: true }); - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(safariResourcesPath, 'src/assets'), - { recursive: true }, - ); - + // Copy locales fs.cpSync( path.resolve(__dirname, './manifest/_locales'), @@ -114,22 +129,19 @@ const prepareBuilds = () => ({ { recursive: true }, ); - // create zip - const zip = new ADMZip(); - zip.addLocalFolder(path.resolve(__dirname, './build/chrome')); - zip.writeZip(path.resolve(__dirname, `./build/chrome-${pkg.version}.zip`)); + // Create distribution zips + console.log('📦 Creating distribution packages...'); + const chromeZip = new ADMZip(); + chromeZip.addLocalFolder(chromeBuildPath); + chromeZip.writeZip(path.resolve(__dirname, `./build/chrome-${pkg.version}.zip`)); + console.log(`✅ Chrome: chrome-${pkg.version}.zip`); - const zip2 = new ADMZip(); - zip2.addLocalFolder(path.resolve(__dirname, './build/firefox')); - zip2.writeZip(path.resolve(__dirname, `./build/firefox-${pkg.version}.zip`)); + const firefoxZip = new ADMZip(); + firefoxZip.addLocalFolder(firefoxBuildPath); + firefoxZip.writeZip(path.resolve(__dirname, `./build/firefox-${pkg.version}.zip`)); + console.log(`✅ Firefox: firefox-${pkg.version}.zip`); - //todo: fix this - // temp copy src for /dist too - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(__dirname, './dist/src/assets'), - { recursive: true }, - ); + console.log('✨ Build complete!'); } }, });