Files
gogh-engine/gogh-theme-engine/vite.config.ts
Aditya Gupta bcb48fd3a6 refactor: options handling and improve code readability
- Cleaned up import statements in options.ts for better organization.
- Enhanced the init function to load settings with improved formatting.
- Streamlined event listener attachments for buttons and inputs.
- Improved the rendering functions for color and semantic grids.
- Updated the parsePalette function in themeEngine.ts for better error handling and readability.
- Refactored deriveSemanticTheme to enhance clarity and maintainability.
- Adjusted tsconfig.json for better structure and readability.
- Updated vite.config.ts to improve build process and maintain consistency.
2026-03-03 23:11:33 +05:30

109 lines
4.1 KiB
TypeScript

import { defineConfig, build as viteBuild, type UserConfig } from 'vite';
import { resolve } from 'path';
import { readFileSync, writeFileSync, mkdirSync, cpSync, existsSync, rmSync } from 'fs';
/**
* Vite build config for the Gogh Theme Engine Chrome Extension.
*
* Chrome MV3 content scripts CANNOT use ES module imports.
* Service workers CAN if the manifest specifies "type": "module".
*
* Strategy:
* • content.ts → IIFE bundle (no imports, self-contained)
* • background.ts → ESM (manifest has "type": "module")
* • options/ → Standard Vite HTML entry
*
* We solve the code-splitting problem by using a custom plugin that
* rebuilds content.ts as a separate IIFE after the main build.
*/
function chromeExtensionPlugin() {
return {
name: 'chrome-extension-iife',
async closeBundle() {
// Rebuild content.ts as a standalone IIFE bundle
console.log('[chrome-ext] Rebuilding content.js as IIFE...');
await viteBuild({
configFile: false,
build: {
outDir: resolve(__dirname, 'dist'),
emptyOutDir: false, // Don't wipe the rest of the build
lib: {
entry: resolve(__dirname, 'src/content.ts'),
name: 'GoghContent',
formats: ['iife'],
fileName: () => 'content.js',
},
rollupOptions: {
output: {
// Ensure it overwrites the ESM version
inlineDynamicImports: true,
},
},
minify: false,
sourcemap: false,
target: 'chrome120',
},
logLevel: 'warn',
});
// Fix options HTML path
const wrongPath = resolve(__dirname, 'dist/src/options/options.html');
const correctDir = resolve(__dirname, 'dist/options');
const correctPath = resolve(correctDir, 'options.html');
if (existsSync(wrongPath) && !existsSync(correctPath)) {
mkdirSync(correctDir, { recursive: true });
const html = readFileSync(wrongPath, 'utf-8');
// Fix script paths — point to the options.js at dist root
const fixedHtml = html
.replace(/src="[^"]*options\.js"/g, 'src="../options.js"')
.replace(/src="\.\.\/\.\.\/options\.js"/g, 'src="../options.js"');
writeFileSync(correctPath, fixedHtml);
}
// Clean up the misplaced src/ directory in dist
const distSrc = resolve(__dirname, 'dist/src');
if (existsSync(distSrc)) {
rmSync(distSrc, { recursive: true, force: true });
}
// Clean up the chunks directory since content.js is now self-contained
// and background.js still needs its chunk import
console.log('[chrome-ext] Build complete.');
},
};
}
export default defineConfig(({ mode }) => {
const isProd = mode === 'production';
return {
plugins: [chromeExtensionPlugin()],
build: {
outDir: 'dist',
emptyOutDir: true,
rollupOptions: {
input: {
background: resolve(__dirname, 'src/background.ts'),
content: resolve(__dirname, 'src/content.ts'),
options: resolve(__dirname, 'src/options/options.html'),
},
output: {
entryFileNames: '[name].js',
chunkFileNames: 'chunks/[name].js',
assetFileNames: 'assets/[name].[ext]',
},
},
minify: isProd ? 'esbuild' : false,
sourcemap: !isProd ? 'inline' : false,
target: 'chrome120',
},
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
},
};
});