UNPKG

@richaadgigi/stylexui

Version:

Build responsive, beautiful interfaces faster than ever with utility-first classes and smart defaults. No bloat. No fuss. Just results.

114 lines (99 loc) 4.62 kB
/** * @richaadgigi/stylexui — withStylexui Next.js Plugin * * Wraps your next.config.js/ts to automatically: * 1. Scan source files for dynamic xui utility classes (e.g. xui-pt-[24px]) * 2. Generate a static CSS file: public/xui-generated.css * 3. Re-extract on every dev reload and production build * * Works with both Webpack and Turbopack. * * Usage in next.config.ts: * const withStylexui = require('@richaadgigi/stylexui/withStylexui'); * module.exports = withStylexui({ ...yourNextConfig }); * * Then add to your root layout's <head>: * <link rel="stylesheet" href="/xui-generated.css" /> * * The runtime xuiDynamicCSS() still handles classes added dynamically at runtime. */ 'use strict'; const path = require('path'); const fs = require('fs'); const { extractDynamicCSS } = require('./scripts/extract-dynamic-css'); // ─── Sync Extraction (Turbopack + Webpack) ──────────────────────────────────── // Runs when next.config is evaluated — before any bundler kicks in. // This ensures public/xui-generated.css always exists before the first request. function runExtractionSync(outputPath, srcPatterns, cwd) { // Run async extraction in a fire-and-forget manner from the sync context. // Node's event loop will process this before webpack/turbopack starts compiling. setImmediate(async () => { try { await extractDynamicCSS({ outputPath, srcPatterns, cwd }); } catch (e) { console.warn('[stylexui] Initial CSS extraction warning:', e.message); } }); } // ─── Webpack Plugin ─────────────────────────────────────────────────────────── // Re-runs extraction before every webpack compilation (handles dev HMR refreshes). class StylexuiWebpackPlugin { constructor(options) { this.options = options; } apply(compiler) { const { outputPath, srcPatterns, cwd } = this.options; compiler.hooks.beforeCompile.tapAsync('StylexuiPlugin', async (params, callback) => { try { await extractDynamicCSS({ outputPath, srcPatterns, cwd }); } catch (e) { console.warn('[stylexui] CSS extraction warning:', e.message); } callback(); }); } } // ─── withStylexui ───────────────────────────────────────────────────────────── /** * Wrap your Next.js config with the StylexUI build plugin. * * @param {object} nextConfig - Your existing Next.js config object * @param {object} [xuiOptions] * @param {string[]} [xuiOptions.srcPatterns] - Custom glob patterns to scan * @param {string} [xuiOptions.outputFile] - Output filename inside public/ (default: 'xui-generated.css') * @returns {object} Modified Next.js config */ function withStylexui(nextConfig = {}, xuiOptions = {}) { const projectRoot = process.cwd(); const outputFileName = xuiOptions.outputFile || 'xui-generated.css'; const publicDir = path.join(projectRoot, 'public'); const outputPath = path.join(publicDir, outputFileName); const srcPatterns = xuiOptions.srcPatterns || [ 'src/**/*.{ts,tsx,js,jsx,html,mdx}', 'app/**/*.{ts,tsx,js,jsx,html,mdx}', 'pages/**/*.{ts,tsx,js,jsx,html,mdx}', 'components/**/*.{ts,tsx,js,jsx,html,mdx}', ]; // Run immediately when next.config is loaded (works with Turbopack + Webpack) runExtractionSync(outputPath, srcPatterns, projectRoot); return { ...nextConfig, // Silence Next.js 15+ warning/error when webpack is modified but turbopack isn't // Dynamic CSS extraction runs synchronously for both, so Turbopack is supported. turbopack: nextConfig.turbopack || {}, webpack(config, context) { // Also hook into webpack for live dev reloads in webpack mode config.plugins.push( new StylexuiWebpackPlugin({ outputPath, srcPatterns, cwd: projectRoot }) ); // Chain existing webpack config if provided if (typeof nextConfig.webpack === 'function') { return nextConfig.webpack(config, context); } return config; }, }; } module.exports = withStylexui; module.exports.default = withStylexui; module.exports.withStylexui = withStylexui;