bertui 0.3.6 → 0.3.8
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 +112 -89
- package/src/server/dev-server.js +12 -11
- package/src/utils/env.js +16 -5
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { join } from 'path';
|
|
1
|
+
import { join, relative, basename } from 'path';
|
|
2
2
|
import { existsSync, mkdirSync, rmSync, cpSync, readdirSync, statSync } from 'fs';
|
|
3
|
-
import { extname,
|
|
3
|
+
import { extname, dirname } from 'path';
|
|
4
4
|
import logger from './logger/logger.js';
|
|
5
5
|
import { buildCSS } from './build/css-builder.js';
|
|
6
|
+
import { loadEnvVariables, replaceEnvInCode } from './utils/env.js'; // ✅ IMPORT THIS!
|
|
6
7
|
|
|
7
8
|
export async function buildProduction(options = {}) {
|
|
8
9
|
const root = options.root || process.cwd();
|
|
@@ -25,8 +26,15 @@ export async function buildProduction(options = {}) {
|
|
|
25
26
|
const startTime = Date.now();
|
|
26
27
|
|
|
27
28
|
try {
|
|
29
|
+
// ✅ LOAD ENV VARS BEFORE COMPILATION!
|
|
30
|
+
logger.info('Step 0: Loading environment variables...');
|
|
31
|
+
const envVars = loadEnvVariables(root);
|
|
32
|
+
if (Object.keys(envVars).length > 0) {
|
|
33
|
+
logger.info(`Loaded ${Object.keys(envVars).length} environment variables`);
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
logger.info('Step 1: Compiling for production...');
|
|
29
|
-
const { routes } = await compileForBuild(root, buildDir);
|
|
37
|
+
const { routes } = await compileForBuild(root, buildDir, envVars); // ✅ PASS ENV VARS!
|
|
30
38
|
logger.success('Production compilation complete');
|
|
31
39
|
|
|
32
40
|
logger.info('Step 2: Building CSS with Lightning CSS...');
|
|
@@ -68,7 +76,21 @@ export async function buildProduction(options = {}) {
|
|
|
68
76
|
chunk: 'chunks/[name]-[hash].js',
|
|
69
77
|
asset: '[name]-[hash].[ext]'
|
|
70
78
|
},
|
|
71
|
-
external: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime']
|
|
79
|
+
external: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime'],
|
|
80
|
+
// ✅ CRITICAL: Add define to replace process.env at bundle time!
|
|
81
|
+
define: {
|
|
82
|
+
'process.env.NODE_ENV': '"production"',
|
|
83
|
+
'process.env.PUBLIC_APP_NAME': JSON.stringify(envVars.PUBLIC_APP_NAME || 'BertUI App'),
|
|
84
|
+
'process.env.PUBLIC_API_URL': JSON.stringify(envVars.PUBLIC_API_URL || ''),
|
|
85
|
+
'process.env.PUBLIC_USERNAME': JSON.stringify(envVars.PUBLIC_USERNAME || ''),
|
|
86
|
+
// Add all other env vars dynamically
|
|
87
|
+
...Object.fromEntries(
|
|
88
|
+
Object.entries(envVars).map(([key, value]) => [
|
|
89
|
+
`process.env.${key}`,
|
|
90
|
+
JSON.stringify(value)
|
|
91
|
+
])
|
|
92
|
+
)
|
|
93
|
+
}
|
|
72
94
|
});
|
|
73
95
|
|
|
74
96
|
if (!result.success) {
|
|
@@ -131,7 +153,8 @@ async function buildAllCSS(root, outDir) {
|
|
|
131
153
|
}
|
|
132
154
|
}
|
|
133
155
|
|
|
134
|
-
|
|
156
|
+
// ✅ ACCEPT ENV VARS PARAMETER
|
|
157
|
+
async function compileForBuild(root, buildDir, envVars) {
|
|
135
158
|
const srcDir = join(root, 'src');
|
|
136
159
|
const pagesDir = join(srcDir, 'pages');
|
|
137
160
|
|
|
@@ -145,7 +168,8 @@ async function compileForBuild(root, buildDir) {
|
|
|
145
168
|
logger.info(`Found ${routes.length} routes`);
|
|
146
169
|
}
|
|
147
170
|
|
|
148
|
-
|
|
171
|
+
// ✅ PASS ENV VARS TO COMPILATION
|
|
172
|
+
await compileBuildDirectory(srcDir, buildDir, root, envVars);
|
|
149
173
|
|
|
150
174
|
if (routes.length > 0) {
|
|
151
175
|
await generateBuildRouter(routes, buildDir);
|
|
@@ -343,7 +367,8 @@ ${routeConfigs}
|
|
|
343
367
|
await Bun.write(join(buildDir, 'router.js'), routerCode);
|
|
344
368
|
}
|
|
345
369
|
|
|
346
|
-
|
|
370
|
+
// ✅ ACCEPT ENV VARS PARAMETER
|
|
371
|
+
async function compileBuildDirectory(srcDir, buildDir, root, envVars) {
|
|
347
372
|
const files = readdirSync(srcDir);
|
|
348
373
|
|
|
349
374
|
for (const file of files) {
|
|
@@ -353,19 +378,20 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
|
|
|
353
378
|
if (stat.isDirectory()) {
|
|
354
379
|
const subBuildDir = join(buildDir, file);
|
|
355
380
|
mkdirSync(subBuildDir, { recursive: true });
|
|
356
|
-
await compileBuildDirectory(srcPath, subBuildDir, root);
|
|
381
|
+
await compileBuildDirectory(srcPath, subBuildDir, root, envVars); // ✅ PASS IT DOWN
|
|
357
382
|
} else {
|
|
358
383
|
const ext = extname(file);
|
|
359
384
|
|
|
360
385
|
if (ext === '.css') continue;
|
|
361
386
|
|
|
362
387
|
if (['.jsx', '.tsx', '.ts'].includes(ext)) {
|
|
363
|
-
await compileBuildFile(srcPath, buildDir, file, root);
|
|
388
|
+
await compileBuildFile(srcPath, buildDir, file, root, envVars); // ✅ PASS IT HERE
|
|
364
389
|
} else if (ext === '.js') {
|
|
365
390
|
const outPath = join(buildDir, file);
|
|
366
391
|
let code = await Bun.file(srcPath).text();
|
|
367
392
|
|
|
368
393
|
code = removeCSSImports(code);
|
|
394
|
+
code = replaceEnvInCode(code, envVars); // ✅ REPLACE ENV VARS!
|
|
369
395
|
code = fixBuildImports(code, srcPath, outPath, root);
|
|
370
396
|
|
|
371
397
|
await Bun.write(outPath, code);
|
|
@@ -374,7 +400,8 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
|
|
|
374
400
|
}
|
|
375
401
|
}
|
|
376
402
|
|
|
377
|
-
|
|
403
|
+
// ✅ ACCEPT ENV VARS PARAMETER
|
|
404
|
+
async function compileBuildFile(srcPath, buildDir, filename, root, envVars) {
|
|
378
405
|
const ext = extname(filename);
|
|
379
406
|
const loader = ext === '.tsx' ? 'tsx' : ext === '.ts' ? 'ts' : 'jsx';
|
|
380
407
|
|
|
@@ -382,6 +409,7 @@ async function compileBuildFile(srcPath, buildDir, filename, root) {
|
|
|
382
409
|
let code = await Bun.file(srcPath).text();
|
|
383
410
|
|
|
384
411
|
code = removeCSSImports(code);
|
|
412
|
+
code = replaceEnvInCode(code, envVars); // ✅ REPLACE ENV VARS BEFORE TRANSPILATION!
|
|
385
413
|
|
|
386
414
|
const outFilename = filename.replace(/\.(jsx|tsx|ts)$/, '.js');
|
|
387
415
|
const outPath = join(buildDir, outFilename);
|
|
@@ -448,41 +476,90 @@ function fixRelativeImports(code) {
|
|
|
448
476
|
return code;
|
|
449
477
|
}
|
|
450
478
|
|
|
451
|
-
// IMPROVED: Extract meta using regex (works on raw source code)
|
|
452
479
|
function extractMetaFromSource(code) {
|
|
453
480
|
try {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
481
|
+
const metaMatch = code.match(/export\s+const\s+meta\s*=\s*\{/);
|
|
482
|
+
if (!metaMatch) return null;
|
|
483
|
+
|
|
484
|
+
const startIndex = metaMatch.index + metaMatch[0].length - 1;
|
|
485
|
+
let braceCount = 0;
|
|
486
|
+
let endIndex = startIndex;
|
|
487
|
+
|
|
488
|
+
for (let i = startIndex; i < code.length; i++) {
|
|
489
|
+
if (code[i] === '{') braceCount++;
|
|
490
|
+
if (code[i] === '}') {
|
|
491
|
+
braceCount--;
|
|
492
|
+
if (braceCount === 0) {
|
|
493
|
+
endIndex = i;
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
457
498
|
|
|
458
|
-
if (
|
|
499
|
+
if (endIndex === startIndex) return null;
|
|
459
500
|
|
|
460
|
-
const
|
|
501
|
+
const metaString = code.substring(startIndex, endIndex + 1);
|
|
461
502
|
const meta = {};
|
|
503
|
+
const pairRegex = /(\w+)\s*:\s*(['"`])((?:(?!\2).)*)\2/g;
|
|
504
|
+
let match;
|
|
462
505
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
pairs.forEach(pair => {
|
|
469
|
-
const [key, value] = pair.split(':').map(s => s.trim());
|
|
470
|
-
meta[key] = value.replace(/['"]/g, '');
|
|
471
|
-
});
|
|
506
|
+
while ((match = pairRegex.exec(metaString)) !== null) {
|
|
507
|
+
const key = match[1];
|
|
508
|
+
const value = match[3];
|
|
509
|
+
meta[key] = value;
|
|
510
|
+
}
|
|
472
511
|
|
|
473
|
-
return meta;
|
|
512
|
+
return Object.keys(meta).length > 0 ? meta : null;
|
|
474
513
|
} catch (error) {
|
|
514
|
+
logger.warn(`Could not extract meta: ${error.message}`);
|
|
475
515
|
return null;
|
|
476
516
|
}
|
|
477
517
|
}
|
|
478
518
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
519
|
+
async function generateProductionHTML(root, outDir, buildResult, routes) {
|
|
520
|
+
const mainBundle = buildResult.outputs.find(o =>
|
|
521
|
+
o.path.includes('main') && o.kind === 'entry-point'
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
if (!mainBundle) {
|
|
525
|
+
throw new Error('Could not find main bundle in build output');
|
|
526
|
+
}
|
|
483
527
|
|
|
484
|
-
const
|
|
485
|
-
|
|
528
|
+
const bundlePath = relative(outDir, mainBundle.path).replace(/\\/g, '/');
|
|
529
|
+
logger.info(`Main bundle path: ${bundlePath}`);
|
|
530
|
+
|
|
531
|
+
const srcStylesDir = join(root, 'src', 'styles');
|
|
532
|
+
let userStylesheets = '';
|
|
533
|
+
|
|
534
|
+
if (existsSync(srcStylesDir)) {
|
|
535
|
+
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
536
|
+
userStylesheets = cssFiles.map(f =>
|
|
537
|
+
` <link rel="stylesheet" href="/styles/${f.replace('.css', '.min.css')}">`
|
|
538
|
+
).join('\n');
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const { loadConfig } = await import('./config/loadConfig.js');
|
|
542
|
+
const config = await loadConfig(root);
|
|
543
|
+
const defaultMeta = config.meta || {};
|
|
544
|
+
|
|
545
|
+
logger.info('Generating SEO-optimized HTML files...');
|
|
546
|
+
|
|
547
|
+
for (const route of routes) {
|
|
548
|
+
if (route.type === 'dynamic') {
|
|
549
|
+
logger.info(`Skipping dynamic route: ${route.route}`);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const sourceCode = await Bun.file(route.path).text();
|
|
554
|
+
const pageMeta = extractMetaFromSource(sourceCode);
|
|
555
|
+
const meta = { ...defaultMeta, ...pageMeta };
|
|
556
|
+
|
|
557
|
+
if (pageMeta) {
|
|
558
|
+
logger.info(`Extracted meta for ${route.route}: ${JSON.stringify(pageMeta)}`);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const html = `<!DOCTYPE html>
|
|
562
|
+
<html lang="${meta.lang || 'en'}">
|
|
486
563
|
<head>
|
|
487
564
|
<meta charset="UTF-8">
|
|
488
565
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
@@ -497,7 +574,7 @@ async function renderComponentToHTML(route, bundlePath, userStylesheets, meta) {
|
|
|
497
574
|
<meta property="og:description" content="${meta.ogDescription || meta.description || 'Built with BertUI'}">
|
|
498
575
|
${meta.ogImage ? `<meta property="og:image" content="${meta.ogImage}">` : ''}
|
|
499
576
|
<meta property="og:type" content="website">
|
|
500
|
-
<meta property="og:url" content="${route}">
|
|
577
|
+
<meta property="og:url" content="${route.route}">
|
|
501
578
|
|
|
502
579
|
<meta name="twitter:card" content="summary_large_image">
|
|
503
580
|
<meta name="twitter:title" content="${meta.ogTitle || meta.title || 'BertUI App'}">
|
|
@@ -505,7 +582,7 @@ async function renderComponentToHTML(route, bundlePath, userStylesheets, meta) {
|
|
|
505
582
|
${meta.ogImage ? `<meta name="twitter:image" content="${meta.ogImage}">` : ''}
|
|
506
583
|
|
|
507
584
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
508
|
-
<link rel="canonical" href="${route}">
|
|
585
|
+
<link rel="canonical" href="${route.route}">
|
|
509
586
|
|
|
510
587
|
${userStylesheets}
|
|
511
588
|
|
|
@@ -519,67 +596,13 @@ ${userStylesheets}
|
|
|
519
596
|
}
|
|
520
597
|
}
|
|
521
598
|
</script>
|
|
522
|
-
|
|
523
|
-
<!-- SEO Preload Hints -->
|
|
524
|
-
<link rel="preconnect" href="https://esm.sh">
|
|
525
|
-
<link rel="dns-prefetch" href="https://esm.sh">
|
|
526
599
|
</head>
|
|
527
600
|
<body>
|
|
528
|
-
<div id="root">
|
|
529
|
-
<!-- App shell - JavaScript will hydrate this -->
|
|
530
|
-
<div style="display:flex;align-items:center;justify-content:center;min-height:100vh;font-family:system-ui">
|
|
531
|
-
<div style="text-align:center">
|
|
532
|
-
<h1 style="font-size:2rem;margin-bottom:1rem">${meta.title || 'Loading...'}</h1>
|
|
533
|
-
<p style="color:#666">${meta.description || 'Please wait while we load your content'}</p>
|
|
534
|
-
</div>
|
|
535
|
-
</div>
|
|
536
|
-
</div>
|
|
601
|
+
<div id="root"></div>
|
|
537
602
|
<script type="module" src="/${bundlePath}"></script>
|
|
538
603
|
</body>
|
|
539
604
|
</html>`;
|
|
540
|
-
|
|
541
|
-
return html;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
async function generateProductionHTML(root, outDir, buildResult, routes) {
|
|
545
|
-
const mainBundle = buildResult.outputs.find(o =>
|
|
546
|
-
o.path.includes('main') && o.kind === 'entry-point'
|
|
547
|
-
);
|
|
548
|
-
|
|
549
|
-
if (!mainBundle) {
|
|
550
|
-
throw new Error('Could not find main bundle in build output');
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const bundlePath = mainBundle.path.replace(outDir, '').replace(/^[\/\\]/, '');
|
|
554
|
-
|
|
555
|
-
const srcStylesDir = join(root, 'src', 'styles');
|
|
556
|
-
let userStylesheets = '';
|
|
557
|
-
|
|
558
|
-
if (existsSync(srcStylesDir)) {
|
|
559
|
-
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
560
|
-
userStylesheets = cssFiles.map(f =>
|
|
561
|
-
` <link rel="stylesheet" href="/styles/${f.replace('.css', '.min.css')}">`
|
|
562
|
-
).join('\n');
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
logger.info('Generating SEO-optimized HTML files...');
|
|
566
|
-
|
|
567
|
-
for (const route of routes) {
|
|
568
|
-
if (route.type === 'dynamic') {
|
|
569
|
-
logger.info(`Skipping dynamic route: ${route.route}`);
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// Read source file and extract meta
|
|
574
|
-
const sourceCode = await Bun.file(route.path).text();
|
|
575
|
-
const meta = extractMetaFromSource(sourceCode) || {};
|
|
576
|
-
|
|
577
|
-
logger.info(`Extracting meta for ${route.route}: ${JSON.stringify(meta)}`);
|
|
578
|
-
|
|
579
|
-
// Generate HTML with meta tags and app shell
|
|
580
|
-
const html = await renderComponentToHTML(route.route, bundlePath, userStylesheets, meta);
|
|
581
605
|
|
|
582
|
-
// Determine output path
|
|
583
606
|
let htmlPath;
|
|
584
607
|
if (route.route === '/') {
|
|
585
608
|
htmlPath = join(outDir, 'index.html');
|
package/src/server/dev-server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import { watch } from 'fs';
|
|
3
3
|
import { join, extname } from 'path';
|
|
4
|
-
import { existsSync } from 'fs';
|
|
4
|
+
import { existsSync, readdirSync } from 'fs'; // ✅ FIXED: Import properly
|
|
5
5
|
import logger from '../logger/logger.js';
|
|
6
6
|
import { compileProject } from '../client/compiler.js';
|
|
7
7
|
import { loadConfig } from '../config/loadConfig.js';
|
|
@@ -50,7 +50,7 @@ export async function startDevServer(options = {}) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
//
|
|
53
|
+
// Handle CSS files from .bertui/styles
|
|
54
54
|
if (path.startsWith('styles/') && path.endsWith('.css')) {
|
|
55
55
|
const cssPath = join(stylesDir, path.replace('styles/', ''));
|
|
56
56
|
const file = Bun.file(cssPath);
|
|
@@ -148,7 +148,6 @@ ws.onclose = () => {
|
|
|
148
148
|
});
|
|
149
149
|
})
|
|
150
150
|
|
|
151
|
-
// FIXED: Serve CSS from .bertui/styles
|
|
152
151
|
.get('/styles/*', async ({ params, set }) => {
|
|
153
152
|
const filepath = join(stylesDir, params['*']);
|
|
154
153
|
const file = Bun.file(filepath);
|
|
@@ -166,7 +165,6 @@ ws.onclose = () => {
|
|
|
166
165
|
});
|
|
167
166
|
})
|
|
168
167
|
|
|
169
|
-
// Around line 60, update the route handler:
|
|
170
168
|
.get('/public/*', async ({ params, set }) => {
|
|
171
169
|
const publicDir = join(root, 'public');
|
|
172
170
|
const filepath = join(publicDir, params['*']);
|
|
@@ -200,17 +198,20 @@ ws.onclose = () => {
|
|
|
200
198
|
function serveHTML(root, hasRouter, config) {
|
|
201
199
|
const meta = config.meta || {};
|
|
202
200
|
|
|
203
|
-
//
|
|
201
|
+
// ✅ FIXED: Proper ESM import for fs
|
|
204
202
|
const srcStylesDir = join(root, 'src', 'styles');
|
|
205
203
|
let userStylesheets = '';
|
|
206
204
|
|
|
207
205
|
if (existsSync(srcStylesDir)) {
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
try {
|
|
207
|
+
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
208
|
+
userStylesheets = cssFiles.map(f => ` <link rel="stylesheet" href="/styles/${f}">`).join('\n');
|
|
209
|
+
} catch (error) {
|
|
210
|
+
logger.warn(`Could not read styles directory: ${error.message}`);
|
|
211
|
+
}
|
|
210
212
|
}
|
|
211
213
|
|
|
212
|
-
const html =
|
|
213
|
-
<!DOCTYPE html>
|
|
214
|
+
const html = `<!DOCTYPE html>
|
|
214
215
|
<html lang="${meta.lang || 'en'}">
|
|
215
216
|
<head>
|
|
216
217
|
<meta charset="UTF-8">
|
|
@@ -226,9 +227,9 @@ function serveHTML(root, hasRouter, config) {
|
|
|
226
227
|
${meta.ogDescription ? `<meta property="og:description" content="${meta.ogDescription || meta.description}">` : ''}
|
|
227
228
|
${meta.ogImage ? `<meta property="og:image" content="${meta.ogImage}">` : ''}
|
|
228
229
|
|
|
229
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
230
|
+
<link rel="icon" type="image/svg+xml" href="/public/favicon.svg">
|
|
230
231
|
|
|
231
|
-
|
|
232
|
+
${userStylesheets}
|
|
232
233
|
|
|
233
234
|
<script type="importmap">
|
|
234
235
|
{
|
package/src/utils/env.js
CHANGED
|
@@ -11,7 +11,7 @@ export function loadEnvVariables(root) {
|
|
|
11
11
|
|
|
12
12
|
// Load from process.env (already loaded by Bun/Node)
|
|
13
13
|
for (const [key, value] of Object.entries(process.env)) {
|
|
14
|
-
// Only expose variables that start with
|
|
14
|
+
// Only expose variables that start with BERTUI_ or PUBLIC_
|
|
15
15
|
if (key.startsWith('BERTUI_') || key.startsWith('PUBLIC_')) {
|
|
16
16
|
envVars[key] = value;
|
|
17
17
|
}
|
|
@@ -28,13 +28,12 @@ export function generateEnvCode(envVars) {
|
|
|
28
28
|
.map(([key, value]) => ` "${key}": ${JSON.stringify(value)}`)
|
|
29
29
|
.join(',\n');
|
|
30
30
|
|
|
31
|
-
return
|
|
32
|
-
// Environment variables injected at build time
|
|
31
|
+
return `// Environment variables injected at build time
|
|
33
32
|
export const env = {
|
|
34
33
|
${envObject}
|
|
35
34
|
};
|
|
36
35
|
|
|
37
|
-
Make it available globally (optional)
|
|
36
|
+
// Make it available globally (optional)
|
|
38
37
|
if (typeof window !== 'undefined') {
|
|
39
38
|
window.__BERTUI_ENV__ = env;
|
|
40
39
|
}
|
|
@@ -42,7 +41,8 @@ if (typeof window !== 'undefined') {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
/**
|
|
45
|
-
* Replace process.env references
|
|
44
|
+
* ✅ CRITICAL FIX: Replace ALL process.env references with actual values
|
|
45
|
+
* This prevents "process is not defined" errors in the browser
|
|
46
46
|
*/
|
|
47
47
|
export function replaceEnvInCode(code, envVars) {
|
|
48
48
|
let result = code;
|
|
@@ -53,5 +53,16 @@ export function replaceEnvInCode(code, envVars) {
|
|
|
53
53
|
result = result.replace(regex, JSON.stringify(value));
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// ✅ NEW: Also replace generic process.env.NODE_ENV
|
|
57
|
+
// This is commonly used by React and other libraries
|
|
58
|
+
result = result.replace(
|
|
59
|
+
/process\.env\.NODE_ENV/g,
|
|
60
|
+
JSON.stringify('production')
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// ✅ NEW: Remove any remaining process references that might cause errors
|
|
64
|
+
// Replace with undefined to avoid runtime errors
|
|
65
|
+
result = result.replace(/\bprocess\b/g, 'undefined');
|
|
66
|
+
|
|
56
67
|
return result;
|
|
57
68
|
}
|