bertui 1.0.0 → 1.0.1
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.
- package/package.json +1 -1
- package/src/build.js +68 -36
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/build.js -
|
|
1
|
+
// src/build.js - COMPLETE FIXED VERSION v1.0.1
|
|
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';
|
|
@@ -45,8 +45,7 @@ export async function buildProduction(options = {}) {
|
|
|
45
45
|
const optimizationTools = await checkOptimizationTools();
|
|
46
46
|
|
|
47
47
|
logger.info('Step 4: Copying and optimizing static assets...');
|
|
48
|
-
|
|
49
|
-
await copyAllStaticAssets(root, outDir);
|
|
48
|
+
await copyAllStaticAssets(root, outDir, false);
|
|
50
49
|
|
|
51
50
|
logger.info('Step 5: Bundling JavaScript with Bun...');
|
|
52
51
|
const buildEntry = join(buildDir, 'main.js');
|
|
@@ -88,14 +87,15 @@ export async function buildProduction(options = {}) {
|
|
|
88
87
|
|
|
89
88
|
logger.success('JavaScript bundled successfully');
|
|
90
89
|
|
|
91
|
-
// DEBUG: Show what was built
|
|
90
|
+
// ✅ DEBUG: Show what was built
|
|
92
91
|
logger.info('Built outputs:');
|
|
93
92
|
result.outputs.forEach((output, i) => {
|
|
94
|
-
|
|
93
|
+
const relativePath = relative(outDir, output.path);
|
|
94
|
+
logger.info(` ${i + 1}. ${relativePath} (${output.kind}, ${output.size} bytes)`);
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
logger.info('Step 6: Generating HTML files...');
|
|
98
|
-
// ✅ CRITICAL FIX: Generate HTML files
|
|
98
|
+
// ✅ CRITICAL FIX: Generate HTML files WITH CSS
|
|
99
99
|
await generateProductionHTML(root, outDir, result, routes);
|
|
100
100
|
|
|
101
101
|
// Clean up build directory
|
|
@@ -136,23 +136,29 @@ export async function buildProduction(options = {}) {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
// ✅ SIMPLE asset copying
|
|
140
|
+
async function copyAllStaticAssets(root, outDir, optimize = true) {
|
|
140
141
|
const publicDir = join(root, 'public');
|
|
141
142
|
const srcImagesDir = join(root, 'src', 'images');
|
|
142
143
|
|
|
143
144
|
logger.info('📦 Copying static assets...');
|
|
144
145
|
|
|
145
|
-
// Copy from public/ to dist/
|
|
146
|
+
// Copy from public/ to root of dist/
|
|
146
147
|
if (existsSync(publicDir)) {
|
|
147
148
|
logger.info(' Copying public/ directory...');
|
|
148
149
|
copyImages(publicDir, outDir);
|
|
150
|
+
} else {
|
|
151
|
+
logger.info(' No public/ directory found');
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
// Copy from src/images/ to dist/images/
|
|
152
155
|
if (existsSync(srcImagesDir)) {
|
|
156
|
+
logger.info(' Copying src/images/ to dist/images/...');
|
|
153
157
|
const distImagesDir = join(outDir, 'images');
|
|
154
|
-
|
|
158
|
+
mkdirSync(distImagesDir, { recursive: true });
|
|
155
159
|
copyImages(srcImagesDir, distImagesDir);
|
|
160
|
+
} else {
|
|
161
|
+
logger.info(' No src/images/ directory found');
|
|
156
162
|
}
|
|
157
163
|
|
|
158
164
|
logger.success('✅ All assets copied');
|
|
@@ -166,6 +172,7 @@ async function buildAllCSS(root, outDir) {
|
|
|
166
172
|
|
|
167
173
|
if (existsSync(srcStylesDir)) {
|
|
168
174
|
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
175
|
+
logger.info(`Found ${cssFiles.length} CSS files to minify`);
|
|
169
176
|
for (const cssFile of cssFiles) {
|
|
170
177
|
const srcPath = join(srcStylesDir, cssFile);
|
|
171
178
|
const destPath = join(stylesOutDir, cssFile.replace('.css', '.min.css'));
|
|
@@ -545,14 +552,9 @@ function extractMetaFromSource(code) {
|
|
|
545
552
|
}
|
|
546
553
|
}
|
|
547
554
|
|
|
548
|
-
// ✅ CRITICAL FIX: Generate HTML files
|
|
555
|
+
// ✅ CRITICAL FIX: Generate HTML files WITH CSS
|
|
549
556
|
async function generateProductionHTML(root, outDir, buildResult, routes) {
|
|
550
|
-
|
|
551
|
-
logger.warn('No routes found, skipping HTML generation');
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
logger.info(`Generating HTML files for ${routes.length} routes...`);
|
|
557
|
+
logger.info('Step 6: Generating HTML files with CSS...');
|
|
556
558
|
|
|
557
559
|
// Find main JS bundle
|
|
558
560
|
const mainBundle = buildResult.outputs.find(o =>
|
|
@@ -560,23 +562,42 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
|
|
|
560
562
|
);
|
|
561
563
|
|
|
562
564
|
if (!mainBundle) {
|
|
563
|
-
logger.error('Could not find main bundle
|
|
564
|
-
// List all outputs for debugging
|
|
565
|
-
logger.info('Available outputs:');
|
|
566
|
-
buildResult.outputs.forEach((o, i) => {
|
|
567
|
-
logger.info(` ${i + 1}. ${o.path} (${o.kind})`);
|
|
568
|
-
});
|
|
565
|
+
logger.error('❌ Could not find main bundle');
|
|
569
566
|
return;
|
|
570
567
|
}
|
|
571
568
|
|
|
572
569
|
const bundlePath = relative(outDir, mainBundle.path).replace(/\\/g, '/');
|
|
573
|
-
logger.info(`Main bundle:
|
|
570
|
+
logger.info(`Main JS bundle: /${bundlePath}`);
|
|
571
|
+
|
|
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
|
+
}
|
|
574
593
|
|
|
575
|
-
// Load config
|
|
594
|
+
// Load config
|
|
576
595
|
const { loadConfig } = await import('./config/loadConfig.js');
|
|
577
596
|
const config = await loadConfig(root);
|
|
578
597
|
const defaultMeta = config.meta || {};
|
|
579
598
|
|
|
599
|
+
logger.info(`Generating HTML for ${routes.length} routes...`);
|
|
600
|
+
|
|
580
601
|
// Generate HTML for each route
|
|
581
602
|
for (const route of routes) {
|
|
582
603
|
try {
|
|
@@ -584,32 +605,30 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
|
|
|
584
605
|
const pageMeta = extractMetaFromSource(sourceCode);
|
|
585
606
|
const meta = { ...defaultMeta, ...pageMeta };
|
|
586
607
|
|
|
587
|
-
const html = generateHTML(meta, route, bundlePath);
|
|
608
|
+
const html = generateHTML(meta, route, bundlePath, cssLinks);
|
|
588
609
|
|
|
589
610
|
let htmlPath;
|
|
590
611
|
if (route.route === '/') {
|
|
591
612
|
htmlPath = join(outDir, 'index.html');
|
|
592
613
|
} else {
|
|
593
|
-
//
|
|
594
|
-
const routeDir = join(outDir, route.route.
|
|
614
|
+
// Remove leading slash for directory creation
|
|
615
|
+
const routeDir = join(outDir, route.route.replace(/^\//, ''));
|
|
595
616
|
mkdirSync(routeDir, { recursive: true });
|
|
596
617
|
htmlPath = join(routeDir, 'index.html');
|
|
597
618
|
}
|
|
598
619
|
|
|
599
620
|
await Bun.write(htmlPath, html);
|
|
600
|
-
logger.success(
|
|
621
|
+
logger.success(`✅ Generated: ${route.route === '/' ? '/' : route.route}`);
|
|
622
|
+
|
|
601
623
|
} catch (error) {
|
|
602
624
|
logger.error(`Failed to generate HTML for ${route.route}: ${error.message}`);
|
|
603
625
|
}
|
|
604
626
|
}
|
|
627
|
+
|
|
628
|
+
logger.success('✨ All HTML files generated with CSS!');
|
|
605
629
|
}
|
|
606
630
|
|
|
607
|
-
function generateHTML(meta, route, bundlePath) {
|
|
608
|
-
const cssFiles = ['global.min.css', 'home.min.css'];
|
|
609
|
-
const stylesheets = cssFiles.map(css =>
|
|
610
|
-
` <link rel="stylesheet" href="/styles/${css}">`
|
|
611
|
-
).join('\n');
|
|
612
|
-
|
|
631
|
+
function generateHTML(meta, route, bundlePath, cssLinks) {
|
|
613
632
|
return `<!DOCTYPE html>
|
|
614
633
|
<html lang="${meta.lang || 'en'}">
|
|
615
634
|
<head>
|
|
@@ -617,13 +636,26 @@ function generateHTML(meta, route, bundlePath) {
|
|
|
617
636
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
618
637
|
<title>${meta.title || 'BertUI App'}</title>
|
|
619
638
|
|
|
620
|
-
<meta name="description" content="${meta.description || 'Built with BertUI
|
|
639
|
+
<meta name="description" content="${meta.description || 'Built with BertUI'}">
|
|
621
640
|
${meta.keywords ? `<meta name="keywords" content="${meta.keywords}">` : ''}
|
|
622
641
|
${meta.author ? `<meta name="author" content="${meta.author}">` : ''}
|
|
642
|
+
${meta.themeColor ? `<meta name="theme-color" content="${meta.themeColor}">` : ''}
|
|
643
|
+
|
|
644
|
+
<meta property="og:title" content="${meta.ogTitle || meta.title || 'BertUI App'}">
|
|
645
|
+
<meta property="og:description" content="${meta.ogDescription || meta.description || 'Built with BertUI'}">
|
|
646
|
+
${meta.ogImage ? `<meta property="og:image" content="${meta.ogImage}">` : ''}
|
|
647
|
+
<meta property="og:type" content="website">
|
|
648
|
+
<meta property="og:url" content="${route.route}">
|
|
649
|
+
|
|
650
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
651
|
+
<meta name="twitter:title" content="${meta.twitterTitle || meta.ogTitle || meta.title || 'BertUI App'}">
|
|
652
|
+
<meta name="twitter:description" content="${meta.twitterDescription || meta.ogDescription || meta.description || 'Built with BertUI'}">
|
|
653
|
+
${meta.twitterImage || meta.ogImage ? `<meta name="twitter:image" content="${meta.twitterImage || meta.ogImage}">` : ''}
|
|
623
654
|
|
|
624
655
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
656
|
+
<link rel="canonical" href="${route.route}">
|
|
625
657
|
|
|
626
|
-
${
|
|
658
|
+
${cssLinks}
|
|
627
659
|
|
|
628
660
|
<script type="importmap">
|
|
629
661
|
{
|