bertui 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/build.js +36 -50
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bertui",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Lightning-fast React dev server powered by Bun and Elysia",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/src/build.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/build.js - COMPLETE FIXED VERSION v1.0.1
1
+ // src/build.js - COMPLETE v1.0.0 FIXED VERSION
2
2
  import { join, relative, basename, extname, dirname } from 'path';
3
3
  import { existsSync, mkdirSync, rmSync, cpSync, readdirSync, statSync } from 'fs';
4
4
  import logger from './logger/logger.js';
@@ -11,7 +11,8 @@ export async function buildProduction(options = {}) {
11
11
  const buildDir = join(root, '.bertuibuild');
12
12
  const outDir = join(root, 'dist');
13
13
 
14
- logger.bigLog('BUILDING FOR PRODUCTION', { color: 'green' });
14
+ logger.bigLog('BUILDING FOR PRODUCTION v1.0.0', { color: 'green' });
15
+ logger.info('🔥 SINGLE CSS FILE SOLUTION - NO BULLSHIT');
15
16
 
16
17
  // Clean up old builds
17
18
  if (existsSync(buildDir)) {
@@ -38,7 +39,7 @@ export async function buildProduction(options = {}) {
38
39
  const { routes } = await compileForBuild(root, buildDir, envVars);
39
40
  logger.success(`Production compilation complete - ${routes.length} routes`);
40
41
 
41
- logger.info('Step 2: Building CSS with Lightning CSS...');
42
+ logger.info('Step 2: Combining ALL CSS into ONE file...');
42
43
  await buildAllCSS(root, outDir);
43
44
 
44
45
  logger.info('Step 3: Checking image optimization tools...');
@@ -87,15 +88,7 @@ export async function buildProduction(options = {}) {
87
88
 
88
89
  logger.success('JavaScript bundled successfully');
89
90
 
90
- // ✅ DEBUG: Show what was built
91
- logger.info('Built outputs:');
92
- result.outputs.forEach((output, i) => {
93
- const relativePath = relative(outDir, output.path);
94
- logger.info(` ${i + 1}. ${relativePath} (${output.kind}, ${output.size} bytes)`);
95
- });
96
-
97
- logger.info('Step 6: Generating HTML files...');
98
- // ✅ CRITICAL FIX: Generate HTML files WITH CSS
91
+ logger.info('Step 6: Generating HTML files with SINGLE CSS...');
99
92
  await generateProductionHTML(root, outDir, result, routes);
100
93
 
101
94
  // Clean up build directory
@@ -108,7 +101,6 @@ export async function buildProduction(options = {}) {
108
101
  logger.success(`✨ Build complete in ${duration}ms`);
109
102
  logger.info(`📦 Output: ${outDir}`);
110
103
 
111
- // Show build summary
112
104
  logger.table(result.outputs.map(o => ({
113
105
  file: o.path.replace(outDir, ''),
114
106
  size: `${(o.size / 1024).toFixed(2)} KB`,
@@ -136,7 +128,7 @@ export async function buildProduction(options = {}) {
136
128
  }
137
129
  }
138
130
 
139
- // SIMPLE asset copying
131
+ // SIMPLE asset copying
140
132
  async function copyAllStaticAssets(root, outDir, optimize = true) {
141
133
  const publicDir = join(root, 'public');
142
134
  const srcImagesDir = join(root, 'src', 'images');
@@ -164,6 +156,7 @@ async function copyAllStaticAssets(root, outDir, optimize = true) {
164
156
  logger.success('✅ All assets copied');
165
157
  }
166
158
 
159
+ // COMBINE ALL CSS INTO ONE FILE
167
160
  async function buildAllCSS(root, outDir) {
168
161
  const srcStylesDir = join(root, 'src', 'styles');
169
162
  const stylesOutDir = join(outDir, 'styles');
@@ -172,12 +165,29 @@ async function buildAllCSS(root, outDir) {
172
165
 
173
166
  if (existsSync(srcStylesDir)) {
174
167
  const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
175
- logger.info(`Found ${cssFiles.length} CSS files to minify`);
168
+ logger.info(`📦 Found ${cssFiles.length} CSS files to combine`);
169
+
170
+ // COMBINE ALL CSS INTO ONE FILE
171
+ let combinedCSS = '';
172
+
176
173
  for (const cssFile of cssFiles) {
177
174
  const srcPath = join(srcStylesDir, cssFile);
178
- const destPath = join(stylesOutDir, cssFile.replace('.css', '.min.css'));
179
- await buildCSS(srcPath, destPath);
175
+ const cssContent = await Bun.file(srcPath).text();
176
+ combinedCSS += `/* === ${cssFile} === */\n${cssContent}\n\n`;
180
177
  }
178
+
179
+ // Write combined CSS
180
+ const combinedPath = join(stylesOutDir, 'bertui.min.css');
181
+ await Bun.write(combinedPath, combinedCSS);
182
+
183
+ // Minify it
184
+ await buildCSS(combinedPath, combinedPath);
185
+
186
+ const size = (await Bun.file(combinedPath).size()) / 1024;
187
+ logger.success(`✅ Combined ${cssFiles.length} CSS files → bertui.min.css (${size.toFixed(1)}KB)`);
188
+
189
+ } else {
190
+ logger.warn('⚠️ No src/styles/ directory found');
181
191
  }
182
192
  }
183
193
 
@@ -552,11 +562,10 @@ function extractMetaFromSource(code) {
552
562
  }
553
563
  }
554
564
 
555
- // CRITICAL FIX: Generate HTML files WITH CSS
565
+ // GENERATE HTML WITH SINGLE CSS FILE
556
566
  async function generateProductionHTML(root, outDir, buildResult, routes) {
557
- logger.info('Step 6: Generating HTML files with CSS...');
567
+ logger.info('Step 6: Generating HTML files with SINGLE CSS...');
558
568
 
559
- // Find main JS bundle
560
569
  const mainBundle = buildResult.outputs.find(o =>
561
570
  o.path.includes('main') && o.kind === 'entry-point'
562
571
  );
@@ -569,28 +578,6 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
569
578
  const bundlePath = relative(outDir, mainBundle.path).replace(/\\/g, '/');
570
579
  logger.info(`Main JS bundle: /${bundlePath}`);
571
580
 
572
- // ✅ CRITICAL FIX: Get CSS files from DIST directory
573
- const stylesOutDir = join(outDir, 'styles');
574
- let cssLinks = '';
575
-
576
- if (existsSync(stylesOutDir)) {
577
- const cssFiles = readdirSync(stylesOutDir).filter(f => f.endsWith('.min.css'));
578
- logger.info(`Found ${cssFiles.length} CSS files: ${cssFiles.join(', ')}`);
579
-
580
- if (cssFiles.length > 0) {
581
- // Create CSS link tags
582
- cssLinks = cssFiles.map(cssFile =>
583
- ` <link rel="stylesheet" href="/styles/${cssFile}">`
584
- ).join('\n');
585
-
586
- logger.info(`Generated CSS links:\n${cssLinks}`);
587
- } else {
588
- logger.warn('⚠️ No .min.css files found in dist/styles/');
589
- }
590
- } else {
591
- logger.error('❌ dist/styles/ directory not found!');
592
- }
593
-
594
581
  // Load config
595
582
  const { loadConfig } = await import('./config/loadConfig.js');
596
583
  const config = await loadConfig(root);
@@ -598,20 +585,18 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
598
585
 
599
586
  logger.info(`Generating HTML for ${routes.length} routes...`);
600
587
 
601
- // Generate HTML for each route
602
588
  for (const route of routes) {
603
589
  try {
604
590
  const sourceCode = await Bun.file(route.path).text();
605
591
  const pageMeta = extractMetaFromSource(sourceCode);
606
592
  const meta = { ...defaultMeta, ...pageMeta };
607
593
 
608
- const html = generateHTML(meta, route, bundlePath, cssLinks);
594
+ const html = generateHTML(meta, route, bundlePath);
609
595
 
610
596
  let htmlPath;
611
597
  if (route.route === '/') {
612
598
  htmlPath = join(outDir, 'index.html');
613
599
  } else {
614
- // Remove leading slash for directory creation
615
600
  const routeDir = join(outDir, route.route.replace(/^\//, ''));
616
601
  mkdirSync(routeDir, { recursive: true });
617
602
  htmlPath = join(routeDir, 'index.html');
@@ -625,10 +610,10 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
625
610
  }
626
611
  }
627
612
 
628
- logger.success('✨ All HTML files generated with CSS!');
613
+ logger.success('✨ All HTML files generated with SINGLE CSS file!');
629
614
  }
630
615
 
631
- function generateHTML(meta, route, bundlePath, cssLinks) {
616
+ function generateHTML(meta, route, bundlePath) {
632
617
  return `<!DOCTYPE html>
633
618
  <html lang="${meta.lang || 'en'}">
634
619
  <head>
@@ -636,7 +621,7 @@ function generateHTML(meta, route, bundlePath, cssLinks) {
636
621
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
637
622
  <title>${meta.title || 'BertUI App'}</title>
638
623
 
639
- <meta name="description" content="${meta.description || 'Built with BertUI'}">
624
+ <meta name="description" content="${meta.description || 'Built with BertUI - Lightning fast React development'}">
640
625
  ${meta.keywords ? `<meta name="keywords" content="${meta.keywords}">` : ''}
641
626
  ${meta.author ? `<meta name="author" content="${meta.author}">` : ''}
642
627
  ${meta.themeColor ? `<meta name="theme-color" content="${meta.themeColor}">` : ''}
@@ -652,11 +637,12 @@ function generateHTML(meta, route, bundlePath, cssLinks) {
652
637
  <meta name="twitter:description" content="${meta.twitterDescription || meta.ogDescription || meta.description || 'Built with BertUI'}">
653
638
  ${meta.twitterImage || meta.ogImage ? `<meta name="twitter:image" content="${meta.twitterImage || meta.ogImage}">` : ''}
654
639
 
640
+ <!-- 🔥 ONE CSS FILE FOR ALL PAGES - NO BULLSHIT -->
641
+ <link rel="stylesheet" href="/styles/bertui.min.css">
642
+
655
643
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">
656
644
  <link rel="canonical" href="${route.route}">
657
645
 
658
- ${cssLinks}
659
-
660
646
  <script type="importmap">
661
647
  {
662
648
  "imports": {