import { defineConfig } from 'vite'; import { resolve } from 'path'; import legacy from '@vitejs/plugin-legacy'; import { glob } from 'glob'; import fs from 'fs'; // Helper to get all Ox core modules function getOxModules() { const files = glob.sync('source/Ox/js/*.js'); const entry = {}; files.forEach(file => { const name = file.replace('source/Ox/js/', '').replace('.js', ''); entry[`ox/${name}`] = resolve(__dirname, file); }); return entry; } export default defineConfig({ build: { lib: { entry: { // Main entry points 'ox': resolve(__dirname, 'source/Ox.js'), 'ox.ui': resolve(__dirname, 'source/UI/UI.js'), 'ox.geo': resolve(__dirname, 'source/Geo/Geo.js'), 'ox.image': resolve(__dirname, 'source/Image/Image.js'), 'ox.unicode': resolve(__dirname, 'source/Unicode/Unicode.js'), // Individual Ox modules for tree-shaking ...getOxModules() }, name: 'Ox', formats: ['es', 'umd', 'iife'] }, rollupOptions: { output: { globals: { // Define any external dependencies here }, assetFileNames: (assetInfo) => { if (assetInfo.name === 'style.css') { return 'ox.css'; } return assetInfo.name; } } }, sourcemap: true, minify: 'terser', outDir: 'dist' }, resolve: { alias: { '@': resolve(__dirname, './source'), 'Ox': resolve(__dirname, './source/Ox'), 'UI': resolve(__dirname, './source/UI'), } }, server: { port: 3000, open: '/examples/' }, plugins: [ legacy({ targets: ['defaults', 'not IE 11'] }), { name: 'ox-theme-processor', async buildStart() { // Process theme files similar to Python build script await processThemes(); } } ], test: { globals: true, environment: 'jsdom', setupFiles: './test/test-setup.js' } }); /** * Process OxJS themes (replaces Python theme processing) */ async function processThemes() { const themesDir = resolve(__dirname, 'source/UI/themes'); const themes = fs.readdirSync(themesDir).filter(d => fs.statSync(resolve(themesDir, d)).isDirectory() && !d.startsWith('.') ); for (const theme of themes) { const themeJsonPath = resolve(themesDir, theme, 'json/theme.jsonc'); if (fs.existsSync(themeJsonPath)) { // Parse JSONC (JSON with comments) const jsonc = fs.readFileSync(themeJsonPath, 'utf-8'); const json = jsonc.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, ''); const themeData = JSON.parse(json); // Process theme CSS const themeCssPath = resolve(__dirname, 'source/UI/css/theme.css'); if (fs.existsSync(themeCssPath)) { let css = fs.readFileSync(themeCssPath, 'utf-8'); // Replace theme variables css = css.replace(/\$(\w+)(\[\d+\])?/g, (match, key, index) => { const value = themeData[key]; if (!value) return match; if (index) { const idx = parseInt(index.slice(1, -1)); return formatColorValue(value[idx]); } return formatColorValue(value); }); // Write processed theme CSS const outputDir = resolve(__dirname, `dist/themes/${theme}/css`); fs.mkdirSync(outputDir, { recursive: true }); fs.writeFileSync(resolve(outputDir, 'theme.css'), css); } } } } function formatColorValue(value) { if (typeof value === 'string') { return value; } if (Array.isArray(value)) { if (Array.isArray(value[0])) { // Multiple color values return value.map(v => `rgb(${v.join(', ')})`).join(', '); } // Single color value return `rgb${value.length === 4 ? 'a' : ''}(${value.join(', ')})`; } return value; }