UNPKG

@moontra/moonui-cli

Version:

CLI tool for MoonUI component library

138 lines (114 loc) 3.75 kB
import fs from 'fs'; import path from 'path'; import type { Plugin } from 'vite'; import { generateThemeCSS } from '../utils/theme-generator'; export interface MoonUIThemePluginOptions { /** * Project root directory path * @default process.cwd() */ projectRoot?: string; /** * Whether to log verbose output * @default true */ verbose?: boolean; /** * CSS file ID to inject theme into * @default 'virtual:moonui-theme.css' */ virtualId?: string; } /** * Vite plugin for MoonUI theme injection * Automatically generates and injects theme CSS based on moonui.config.js */ export function moonuiThemePlugin(options: MoonUIThemePluginOptions = {}): Plugin { const virtualId = options.virtualId || 'virtual:moonui-theme.css'; const resolvedVirtualId = '\0' + virtualId; const projectRoot = options.projectRoot || process.cwd(); const configPath = path.join(projectRoot, 'moonui.config.js'); let themeCSS: string | null = null; function generateTheme(): string { try { // Check if config exists if (!fs.existsSync(configPath)) { console.warn('[MoonUI Vite] moonui.config.js not found. Using default theme.'); return generateThemeCSS({}); } // Clear module cache to get fresh config delete require.cache[configPath]; // Load the config const config = require(configPath); // Check if automatic CSS generation is enabled if (config.build?.generateThemeCSS === false) { return ''; } // Generate theme CSS (now scoped to .moonui-theme class) const css = generateThemeCSS(config.theme || {}); // Log success if (options.verbose !== false) { console.log('[MoonUI Vite] Theme CSS generated successfully (scoped to .moonui-theme)'); } return css; } catch (error) { console.error('[MoonUI Vite] Error generating theme CSS:', error); return ''; } } return { name: 'moonui-theme', // Handle virtual module resolveId(id: string) { if (id === virtualId) { return resolvedVirtualId; } return null; }, // Load virtual module content load(id: string) { if (id === resolvedVirtualId) { if (!themeCSS) { themeCSS = generateTheme(); } return themeCSS; } return null; }, // Handle HMR handleHotUpdate({ file, server }: { file: string; server: any }) { if (file === configPath) { // Regenerate theme CSS themeCSS = generateTheme(); // Trigger HMR for the virtual module const module = server.moduleGraph.getModuleById(resolvedVirtualId); if (module) { server.reloadModule(module); } if (options.verbose !== false) { console.log('[MoonUI Vite] Theme updated due to config change'); } } }, // Transform CSS imports to include virtual module transform(code: string, id: string) { // Only process CSS files if (!id.endsWith('.css')) return null; // Check if this is a main CSS file (e.g., index.css, app.css, global.css) const isMainCSS = /\/(index|app|global|main|styles)\.css$/.test(id); if (!isMainCSS) return null; // Check if the virtual module is already imported if (code.includes(virtualId)) return null; // Add import at the beginning const importStatement = `@import '${virtualId}';\n\n`; return { code: importStatement + code, map: null }; } }; } /** * Default export for easier importing */ export default moonuiThemePlugin;