vaderjs 1.3.3-763562-hotfix → 1.3.3-7722242
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/vader.js +303 -284
package/package.json
CHANGED
package/vader.js
CHANGED
|
@@ -143,9 +143,6 @@ function Compiler(func, file) {
|
|
|
143
143
|
isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
|
-
if (isJSXComponent) {
|
|
147
|
-
continue
|
|
148
|
-
}
|
|
149
146
|
// add ; after newlines
|
|
150
147
|
|
|
151
148
|
|
|
@@ -242,34 +239,34 @@ function Compiler(func, file) {
|
|
|
242
239
|
continue;
|
|
243
240
|
}
|
|
244
241
|
let old = spread;
|
|
245
|
-
spread = spread.trim().replace(/\s+/g, " ");
|
|
242
|
+
spread = spread.trim().replace(/\s+/g, " ");
|
|
246
243
|
// re,pve $={ and }
|
|
247
244
|
spread = spread.replace(/\s*\$\s*=\s*{\s*{/gs, '')
|
|
248
|
-
|
|
245
|
+
|
|
249
246
|
// replace trailing }
|
|
250
|
-
spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
|
|
251
|
-
let splitByCommas =
|
|
247
|
+
spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
|
|
248
|
+
let splitByCommas = spread.split(/,(?![^{}]*})/gs)
|
|
252
249
|
// remove empty strings
|
|
253
250
|
splitByCommas = splitByCommas.filter((e) => e.split(':')[0].trim().length > 0)
|
|
254
|
-
splitByCommas = splitByCommas.map((e, index) => {
|
|
251
|
+
splitByCommas = splitByCommas.map((e, index) => {
|
|
255
252
|
let key = e.split(':')[0].trim()
|
|
256
253
|
switch (true) {
|
|
257
254
|
case e.includes('function') && !e.includes('this.bind') || e && e.includes('=>') && !e.includes('this.bind'):
|
|
258
255
|
let value = e.split(':')[1].trim()
|
|
259
|
-
let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
|
|
256
|
+
let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
|
|
260
257
|
value = `this.bind(${value}, false, "${ref}", "")`
|
|
261
258
|
e = `${key}="\${${value}}"`
|
|
262
259
|
break;
|
|
263
|
-
case
|
|
264
|
-
let v2 = e.split('style:')[1].trim().replace(/,$/, '')
|
|
265
|
-
v2 = v2.replace(/,$/, '')
|
|
260
|
+
case e.includes('style:'):
|
|
261
|
+
let v2 = e.split('style:')[1].trim().replace(/,$/, '')
|
|
262
|
+
v2 = v2.replace(/,$/, '')
|
|
266
263
|
e = `${key}="\${this.parseStyle(${v2})}"`
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
default:
|
|
270
|
-
let v = e.split(':')
|
|
264
|
+
break;
|
|
265
|
+
|
|
266
|
+
default:
|
|
267
|
+
let v = e.split(':')
|
|
271
268
|
key = v[0].trim()
|
|
272
|
-
|
|
269
|
+
// remove key from v
|
|
273
270
|
v.shift()
|
|
274
271
|
v = v.join(' ')
|
|
275
272
|
e = `${key}="\${${v}}"`
|
|
@@ -280,7 +277,7 @@ function Compiler(func, file) {
|
|
|
280
277
|
|
|
281
278
|
return e;
|
|
282
279
|
});
|
|
283
|
-
|
|
280
|
+
|
|
284
281
|
|
|
285
282
|
let newSpread = splitByCommas.join(' ').trim().replace(/,$/, '');
|
|
286
283
|
|
|
@@ -351,7 +348,7 @@ function Compiler(func, file) {
|
|
|
351
348
|
newAttributes.push(attribute);
|
|
352
349
|
for (let key in attributes) {
|
|
353
350
|
|
|
354
|
-
let value = attributes[key];
|
|
351
|
+
let value = attributes[key];
|
|
355
352
|
let oldvalue = value;
|
|
356
353
|
if (value && !value.new) {
|
|
357
354
|
|
|
@@ -482,16 +479,11 @@ function Compiler(func, file) {
|
|
|
482
479
|
|
|
483
480
|
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
484
481
|
let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
let props = component.split("<")[1].split(">")[0]
|
|
482
|
+
const dynamicAttributesRegex = /(\w+)(?:="([^"]*?)"|='([^']*?)'|(?:=\{([^}]*?)\})?|(?:=\{(.*?)*\})?|(?:={([^}]*?)})?|(?:{([^}]*?)})?|(?:}))?|\$=\s*\{\s*\{\s*([^]*?)\s*\}\s*\}/gs;
|
|
489
483
|
|
|
490
484
|
|
|
491
|
-
const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{.*.*\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*\})?|\{[^}]*\})|\[[^\]]*\])/gs;
|
|
492
|
-
|
|
493
|
-
const attributeObject = {};
|
|
494
485
|
|
|
486
|
+
let props = component.match(dynamicAttributesRegex)
|
|
495
487
|
|
|
496
488
|
let filteredProps = [];
|
|
497
489
|
let isWithinComponent = false;
|
|
@@ -500,31 +492,76 @@ function Compiler(func, file) {
|
|
|
500
492
|
|
|
501
493
|
let $_ternaryprops = []
|
|
502
494
|
|
|
503
|
-
let
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
495
|
+
for (let prop of props) {
|
|
496
|
+
|
|
497
|
+
if (prop === componentName) {
|
|
498
|
+
|
|
499
|
+
isWithinComponent = true;
|
|
500
|
+
filteredProps.push(prop);
|
|
501
|
+
} else if (isWithinComponent && prop.includes('=')) {
|
|
502
|
+
|
|
503
|
+
if (prop.startsWith('$=')) {
|
|
504
|
+
let old = prop
|
|
505
|
+
prop = prop.replace(/\$\s*=\s*\{\s*\{\s*([^]*?)\s*\}\s*\}/gs, '$1')
|
|
506
|
+
component = component.replace(old, '')
|
|
507
|
+
componentAttributes = componentAttributes.replace(prop, '')
|
|
508
|
+
$_ternaryprops.push(prop)
|
|
509
|
+
|
|
510
|
+
}
|
|
511
|
+
else if (prop.includes('${')) {
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
prop = prop.replace('="', ':')
|
|
515
|
+
if (prop.includes('${')) {
|
|
516
|
+
prop = prop.replace('="', ':')
|
|
517
|
+
prop = prop.replace('${', '')
|
|
518
|
+
}
|
|
519
|
+
if (prop.includes('="${{')) {
|
|
520
|
+
prop = prop.replace('${{', '{')
|
|
521
|
+
prop = prop.replace('}}', '}')
|
|
522
|
+
prop = prop.replace('="', ':')
|
|
523
|
+
prop = prop.replace('}"', '}')
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
}
|
|
527
|
+
if (prop.includes('={')) {
|
|
528
|
+
let value = prop.split('={')
|
|
529
|
+
let isObj = value[1].match(/^{.*}$/gs) ? true : false
|
|
530
|
+
if (!isObj) {
|
|
531
|
+
// remove trailing }
|
|
532
|
+
value[1] = value[1].replace(/}\s*$/, '')
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (value[0] == 'style' && isObj) {
|
|
536
|
+
value[1] = `this.parseStyle(${value[1]})`
|
|
537
|
+
}
|
|
538
|
+
prop = `${value[0]}:${value[1]}`
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (prop.includes('function') || prop.includes('=>')) {
|
|
542
|
+
// parse 'function' to function
|
|
543
|
+
prop = prop.replace("'", '')
|
|
544
|
+
|
|
545
|
+
if (prop.endsWith("}'")) {
|
|
546
|
+
prop = prop.replace("}'", '}')
|
|
547
|
+
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
prop = prop.replace('=function', ':function')
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
filteredProps.push(prop);
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
} else if (isWithinComponent && prop.includes('}')) {
|
|
558
|
+
|
|
518
559
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
} else {
|
|
524
|
-
// remove starting { and ending } using regex
|
|
525
|
-
value = value.replace(/^{/, '').replace(/}$/, '')
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
else {
|
|
563
|
+
isWithinComponent = false;
|
|
526
564
|
}
|
|
527
|
-
propstring += `${key}:${value},`
|
|
528
565
|
}
|
|
529
566
|
component = component.replaceAll(/\s+/g, " ");
|
|
530
567
|
|
|
@@ -535,7 +572,7 @@ function Compiler(func, file) {
|
|
|
535
572
|
|
|
536
573
|
let children = new RegExp(`<${name}[^>]*>([^]*)<\/${name}>`, 'gs').exec(component)?.[1] || null;
|
|
537
574
|
|
|
538
|
-
|
|
575
|
+
props = filteredProps.join(',').replace(/\s+/g, " ").trim().replace(/,$/, '')
|
|
539
576
|
|
|
540
577
|
let savedname = name;
|
|
541
578
|
|
|
@@ -568,15 +605,24 @@ function Compiler(func, file) {
|
|
|
568
605
|
|
|
569
606
|
|
|
570
607
|
|
|
571
|
-
|
|
608
|
+
|
|
609
|
+
props = props.replaceAll(`,${savedname}`, '').replaceAll(savedname, '')
|
|
610
|
+
if (props.startsWith(',')) {
|
|
611
|
+
props = props.replace(',', '')
|
|
612
|
+
}
|
|
613
|
+
props = props.replaceAll("='", ":'")
|
|
614
|
+
.replaceAll('=`', ':`')
|
|
615
|
+
.replaceAll('="', ':"')
|
|
616
|
+
.replaceAll('={', ':')
|
|
572
617
|
|
|
573
618
|
|
|
574
619
|
/**
|
|
575
620
|
* @memoize - memoize a component to be remembered on each render and replace the old jsx
|
|
576
621
|
*/
|
|
577
622
|
|
|
623
|
+
|
|
578
624
|
let replace = "";
|
|
579
|
-
replace = `\${this.memoize(this.createComponent(${savedname}, {${
|
|
625
|
+
replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join('')}\`]))}`;
|
|
580
626
|
|
|
581
627
|
|
|
582
628
|
body = body.replace(before, replace);
|
|
@@ -592,49 +638,47 @@ function Compiler(func, file) {
|
|
|
592
638
|
let replaceMents = [];
|
|
593
639
|
|
|
594
640
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
let dest = file.split('node_modules')[1]
|
|
623
|
-
dest = dest.split(baseFolder)[1]
|
|
624
|
-
writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
|
|
625
|
-
let importname = match.split('import')[1].split('from')[0].trim()
|
|
626
|
-
let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
627
|
-
let newImport = `/src/${baseFolder + dest}`
|
|
628
|
-
newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
|
|
629
|
-
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
630
|
-
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
641
|
+
for (let match of imports) {
|
|
642
|
+
let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
643
|
+
switch (true) {
|
|
644
|
+
case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
|
|
645
|
+
let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
|
|
646
|
+
componentFolder = componentFolder.split(process.cwd())[1]
|
|
647
|
+
if (!fs.existsSync(process.cwd() + componentFolder)) {
|
|
648
|
+
throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
|
|
652
|
+
fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
|
|
656
|
+
let glp = globSync('**/**/**/**.{jsx,js}', {
|
|
657
|
+
cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
|
|
658
|
+
absolute: true,
|
|
659
|
+
recursive: true
|
|
660
|
+
})
|
|
661
|
+
for (let file of glp) {
|
|
662
|
+
let text = fs.readFileSync(file, "utf8");
|
|
663
|
+
if (!file.endsWith('.js') && file.endsWith('.jsx')) {
|
|
664
|
+
text = Compiler(text, file);
|
|
665
|
+
|
|
631
666
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
667
|
+
let dest = file.split('node_modules')[1]
|
|
668
|
+
dest = dest.split(baseFolder)[1]
|
|
669
|
+
writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
|
|
670
|
+
let importname = match.split('import')[1].split('from')[0].trim()
|
|
671
|
+
let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
672
|
+
let newImport = `/src/${baseFolder + dest}`
|
|
673
|
+
newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
|
|
674
|
+
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
675
|
+
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
break;
|
|
680
|
+
default:
|
|
681
|
+
break;
|
|
638
682
|
}
|
|
639
683
|
}
|
|
640
684
|
|
|
@@ -827,8 +871,6 @@ const glb = await glob("**/**/**/**.{jsx,js}", {
|
|
|
827
871
|
absolute: true,
|
|
828
872
|
recursive: true
|
|
829
873
|
});
|
|
830
|
-
let hasRendered = []
|
|
831
|
-
|
|
832
874
|
async function Build() {
|
|
833
875
|
globalThis.isBuilding = true
|
|
834
876
|
console.log(globalThis.isProduction ? 'Creating Optimized Production Build\n' : '')
|
|
@@ -843,133 +885,191 @@ async function Build() {
|
|
|
843
885
|
|
|
844
886
|
function ssg(routes = []) {
|
|
845
887
|
globalThis.isBuilding = true
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
fs.readFile(filePath, (err, data) => {
|
|
856
|
-
if (err) {
|
|
857
|
-
res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
|
|
858
|
-
res.end('File not found');
|
|
888
|
+
routes.forEach(async (route) => {
|
|
889
|
+
if (route.url.includes(':')) {
|
|
890
|
+
return
|
|
891
|
+
}
|
|
892
|
+
let equalparamroute = routes.map((e) => {
|
|
893
|
+
if (e.url.includes(':')) {
|
|
894
|
+
let url = e.url.split('/:')[0]
|
|
895
|
+
if (url && route.url === url) {
|
|
896
|
+
return e
|
|
859
897
|
} else {
|
|
860
|
-
|
|
861
|
-
|
|
898
|
+
return null
|
|
899
|
+
|
|
862
900
|
}
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
|
|
901
|
+
}
|
|
902
|
+
return null
|
|
903
|
+
}).filter(Boolean)
|
|
904
|
+
let document = `
|
|
905
|
+
<!DOCTYPE html>
|
|
906
|
+
<html lang="en">
|
|
907
|
+
<head>
|
|
908
|
+
<script>
|
|
909
|
+
window.routes = JSON.parse('${JSON.stringify(routes)}')
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
</script>
|
|
913
|
+
<script id="isServer">
|
|
914
|
+
window.isServer = true
|
|
915
|
+
</script>
|
|
916
|
+
<meta charset="UTF-8">
|
|
917
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
918
|
+
<script type="module" id="meta">
|
|
919
|
+
window.history.pushState({}, '', '${route.url}')
|
|
920
|
+
|
|
921
|
+
</script>
|
|
922
|
+
<script type="module" id="router">
|
|
923
|
+
import VaderRouter from '/router.js'
|
|
924
|
+
const router = new VaderRouter('${route.url}', 3000)
|
|
925
|
+
router.get('${route.url}', async (req, res) => {
|
|
926
|
+
try{
|
|
927
|
+
let module = await import('/${route.fileName.replace('.jsx', '.js')}')
|
|
928
|
+
if(Object.keys(module).includes('$prerender') && !module.$prerender){
|
|
929
|
+
document.head.setAttribute('prerender', 'false')
|
|
930
|
+
}
|
|
931
|
+
res.render(module, req, res, module.$metadata)
|
|
932
|
+
}
|
|
933
|
+
catch(error){
|
|
934
|
+
let errorMessage = {
|
|
935
|
+
message: error.message,
|
|
936
|
+
name: error.name,
|
|
937
|
+
stack: error.stack,
|
|
938
|
+
path: window.location.pathname
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
|
|
943
|
+
throw new Error(error)
|
|
944
|
+
}
|
|
945
|
+
})
|
|
946
|
+
${equalparamroute.length > 0 ? equalparamroute.map((e) => {
|
|
866
947
|
|
|
867
|
-
let port = 12000
|
|
868
|
-
server.on('error', (err) => {
|
|
869
|
-
if (err.code === 'EADDRINUSE') {
|
|
870
|
-
setTimeout(() => {
|
|
871
|
-
server.close();
|
|
872
|
-
server.listen(++port);
|
|
873
|
-
}, 1000);
|
|
874
|
-
}
|
|
875
|
-
})
|
|
876
948
|
|
|
877
|
-
const browser = puppeteer.launch({
|
|
878
|
-
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
879
|
-
warning: false,
|
|
880
|
-
})
|
|
881
|
-
server.listen(port);
|
|
882
949
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
950
|
+
return `router.get('${e.url}', async (req, res) => {
|
|
951
|
+
let module = await import('/${e.fileName.replace('.jsx', '.js')}')
|
|
952
|
+
res.render(module, req, res, module.$metadata)
|
|
953
|
+
})\n`
|
|
954
|
+
}) : ''}
|
|
955
|
+
router.listen(3000)
|
|
956
|
+
|
|
957
|
+
</script>
|
|
958
|
+
</head>
|
|
959
|
+
<body>
|
|
960
|
+
<div id="root"></div>
|
|
961
|
+
</body>
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
</html>
|
|
965
|
+
`;
|
|
966
|
+
|
|
967
|
+
// generate random but common ports
|
|
968
|
+
let port = Math.floor(Math.random() * (65535 - 49152 + 1) + 49152)
|
|
969
|
+
|
|
970
|
+
const server = http.createServer((req, res) => {
|
|
971
|
+
|
|
972
|
+
if (req.url === '/') {
|
|
973
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
974
|
+
res.end(document);
|
|
975
|
+
} else {
|
|
976
|
+
// Serve static files (adjust the file paths based on your project structure)
|
|
977
|
+
const filePath = process.cwd() + '/dist/' + req.url
|
|
978
|
+
|
|
979
|
+
fs.readFile(filePath, (err, data) => {
|
|
980
|
+
if (err) {
|
|
981
|
+
res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
|
|
982
|
+
res.end('File not found');
|
|
983
|
+
} else {
|
|
984
|
+
res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
|
|
985
|
+
res.end(data);
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
server.listen(port)
|
|
992
|
+
server.on('error', (err) => {
|
|
993
|
+
if (err.code === 'EADDRINUSE') {
|
|
994
|
+
console.log(`Port ${port} is in use, trying another port...`);
|
|
995
|
+
setTimeout(() => {
|
|
996
|
+
server.close();
|
|
997
|
+
server.listen(++port);
|
|
998
|
+
}, 1000);
|
|
999
|
+
}
|
|
1000
|
+
})
|
|
1001
|
+
|
|
887
1002
|
globalThis.listen = true;
|
|
888
1003
|
|
|
1004
|
+
const browser = await puppeteer.launch({
|
|
1005
|
+
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
1006
|
+
warning: false,
|
|
1007
|
+
})
|
|
889
1008
|
try {
|
|
890
1009
|
|
|
891
1010
|
route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
|
|
892
|
-
let page =
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
});
|
|
904
|
-
} catch (error) {
|
|
905
|
-
page.close()
|
|
906
|
-
}
|
|
907
|
-
page.on('crash', () => {
|
|
908
|
-
console.error(`Render process crashed for ${route.url}`)
|
|
909
|
-
});
|
|
910
|
-
page.on('requestfailed', request => {
|
|
911
|
-
console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
|
|
1011
|
+
let page = await browser.newPage();
|
|
1012
|
+
// Handle browser errors
|
|
1013
|
+
page.on('error', (err) => {
|
|
1014
|
+
console.error('BROWSER ERROR:', JSON.parse(err));
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
try {
|
|
1018
|
+
page.on('pageerror', async err => {
|
|
1019
|
+
let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
|
|
1020
|
+
console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
|
|
1021
|
+
|
|
912
1022
|
});
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
browser.close()
|
|
1025
|
+
}
|
|
1026
|
+
// Handle page crashes
|
|
1027
|
+
page.on('crash', () => {
|
|
1028
|
+
console.error('PAGE CRASHED');
|
|
1029
|
+
});
|
|
1030
|
+
page.on('requestfailed', request => {
|
|
1031
|
+
console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
|
|
1032
|
+
});
|
|
1033
|
+
await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle2' });
|
|
1034
|
+
|
|
1035
|
+
|
|
924
1036
|
|
|
925
|
-
html = await prettier.format(html, { parser: "html" })
|
|
926
1037
|
|
|
927
|
-
writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
928
1038
|
|
|
929
|
-
console.log(`\x1b[32m%s\x1b[0m`, `Prerendered ${route.url}...`)
|
|
930
1039
|
|
|
931
|
-
|
|
1040
|
+
|
|
1041
|
+
await page.evaluate(() => {
|
|
1042
|
+
document.getElementById('meta').remove()
|
|
1043
|
+
document.querySelector('#isServer').innerHTML = 'window.isServer = false'
|
|
1044
|
+
if (document.head.getAttribute('prerender') === 'false') {
|
|
1045
|
+
document.querySelector('#root').innerHTML = ''
|
|
1046
|
+
console.log(`Disabled prerendering for ${window.location.pathname}`)
|
|
1047
|
+
}
|
|
932
1048
|
})
|
|
1049
|
+
let html = await page.content();
|
|
933
1050
|
|
|
1051
|
+
html = await prettier.format(html, { parser: "html" })
|
|
934
1052
|
|
|
935
1053
|
|
|
1054
|
+
await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
936
1055
|
|
|
937
|
-
} catch (error) {
|
|
938
|
-
console.log('\x1b[31m%s\x1b[0m', 'Error:', error)
|
|
939
1056
|
|
|
1057
|
+
} catch (error) {
|
|
1058
|
+
console.log(error)
|
|
940
1059
|
}
|
|
1060
|
+
|
|
941
1061
|
finally {
|
|
1062
|
+
browser.close()
|
|
1063
|
+
server.close()
|
|
942
1064
|
}
|
|
943
1065
|
})
|
|
944
1066
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
function kill() {
|
|
950
|
-
console.log(`\x1b[32m%s\x1b[0m`, `\nPrerendered ${routes.length} pages...\n`)
|
|
951
|
-
server.close()
|
|
952
|
-
browser.then((browser) => {
|
|
953
|
-
browser.close()
|
|
954
|
-
})
|
|
955
|
-
hasRendered = []
|
|
1067
|
+
let timeout = setTimeout(() => {
|
|
956
1068
|
globalThis.isBuilding = false
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
if (hasRendered.length === routes.length) {
|
|
962
|
-
kill()
|
|
963
|
-
} else {
|
|
964
|
-
console.log(`\x1b[32m%s\x1b[0m`, `Prerendering ${routes.length} pages...\n`)
|
|
965
|
-
let interval = setInterval(() => {
|
|
966
|
-
if (hasRendered.length === routes.length) {
|
|
967
|
-
kill()
|
|
968
|
-
clearInterval(interval)
|
|
969
|
-
}
|
|
970
|
-
}, 1000);
|
|
971
|
-
}
|
|
1069
|
+
clearTimeout(timeout)
|
|
1070
|
+
}, 1000)
|
|
972
1071
|
}
|
|
1072
|
+
|
|
973
1073
|
globalThis.routes = []
|
|
974
1074
|
|
|
975
1075
|
for await (let file of glb) {
|
|
@@ -1069,9 +1169,7 @@ async function Build() {
|
|
|
1069
1169
|
}
|
|
1070
1170
|
|
|
1071
1171
|
|
|
1072
|
-
|
|
1073
|
-
globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1074
|
-
}
|
|
1172
|
+
globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1075
1173
|
|
|
1076
1174
|
|
|
1077
1175
|
let stats = {
|
|
@@ -1088,84 +1186,6 @@ async function Build() {
|
|
|
1088
1186
|
globalThis.isProduction ? console.log(string) : null
|
|
1089
1187
|
}
|
|
1090
1188
|
|
|
1091
|
-
globalThis.routeDocuments = []
|
|
1092
|
-
globalThis.routes.map((route) => {
|
|
1093
|
-
let equalparamroute = globalThis.routes.map((e) => {
|
|
1094
|
-
if (e.url.includes(':')) {
|
|
1095
|
-
let url = e.url.split('/:')[0]
|
|
1096
|
-
if (url && route.url === url) {
|
|
1097
|
-
return e
|
|
1098
|
-
} else {
|
|
1099
|
-
return null
|
|
1100
|
-
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
return null
|
|
1104
|
-
}).filter(Boolean)
|
|
1105
|
-
let document = `
|
|
1106
|
-
<!DOCTYPE html>
|
|
1107
|
-
<html lang="en">
|
|
1108
|
-
<head>
|
|
1109
|
-
<script>
|
|
1110
|
-
window.routes = JSON.parse('${JSON.stringify(globalThis.routes)}')
|
|
1111
|
-
</script>
|
|
1112
|
-
<script type="module" id="meta">
|
|
1113
|
-
window.history.pushState({}, '', '${route.url}')
|
|
1114
|
-
|
|
1115
|
-
</script>
|
|
1116
|
-
<script id="isServer">
|
|
1117
|
-
window.isServer = true
|
|
1118
|
-
</script>
|
|
1119
|
-
<meta charset="UTF-8">
|
|
1120
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
1121
|
-
|
|
1122
|
-
<script type="module" id="router">
|
|
1123
|
-
import VaderRouter from '/router.js'
|
|
1124
|
-
const router = new VaderRouter('${route.url}')
|
|
1125
|
-
router.get('${route.url}', async (req, res) => {
|
|
1126
|
-
try{
|
|
1127
|
-
let module = await import('/${route.fileName.replace('.jsx', '.js')}')
|
|
1128
|
-
if(Object.keys(module).includes('$prerender') && !module.$prerender){
|
|
1129
|
-
document.head.setAttribute('prerender', 'false')
|
|
1130
|
-
}
|
|
1131
|
-
res.render(module, req, res, module.$metadata)
|
|
1132
|
-
}
|
|
1133
|
-
catch(error){
|
|
1134
|
-
let errorMessage = {
|
|
1135
|
-
message: error.message,
|
|
1136
|
-
name: error.name,
|
|
1137
|
-
stack: error.stack,
|
|
1138
|
-
path: window.location.pathname
|
|
1139
|
-
};
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
|
|
1143
|
-
throw new Error(error)
|
|
1144
|
-
}
|
|
1145
|
-
})
|
|
1146
|
-
${equalparamroute.length > 0 ? equalparamroute.map((e) => {
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
return `router.get('${e.url}', async (req, res) => {
|
|
1151
|
-
let module = await import('/${e.fileName.replace('.jsx', '.js')}')
|
|
1152
|
-
res.render(module, req, res, module.$metadata)
|
|
1153
|
-
})\n`
|
|
1154
|
-
}) : ''}
|
|
1155
|
-
router.listen(3000)
|
|
1156
|
-
|
|
1157
|
-
</script>
|
|
1158
|
-
</head>
|
|
1159
|
-
<body>
|
|
1160
|
-
<div id="root"></div>
|
|
1161
|
-
</body>
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
</html>
|
|
1165
|
-
`;
|
|
1166
|
-
globalThis.routeDocuments.push({ url: route.url, document: document })
|
|
1167
|
-
})
|
|
1168
|
-
|
|
1169
1189
|
ssg(globalThis.routes)
|
|
1170
1190
|
|
|
1171
1191
|
|
|
@@ -1194,10 +1214,11 @@ async function Build() {
|
|
|
1194
1214
|
scannedSourceFiles.forEach(async (file) => {
|
|
1195
1215
|
file = file.replace(/\\/g, '/');
|
|
1196
1216
|
let name = file.split('/src/')[1]
|
|
1217
|
+
//parse jsx
|
|
1197
1218
|
|
|
1198
1219
|
let data = await reader(process.cwd() + "/src/" + name)
|
|
1199
1220
|
if (name.includes('.jsx')) {
|
|
1200
|
-
let origin = process.cwd() + "/src/" + name
|
|
1221
|
+
let origin = process.cwd() + "/src/" + name
|
|
1201
1222
|
if (!globalThis.isProduction) {
|
|
1202
1223
|
let { sourceMap } = sourceMapGen({ origin: origin, fileName: name }, await Compiler(data, origin))
|
|
1203
1224
|
data = data + `\n//# sourceMappingURL=/src/maps/${name.replace('.jsx', '.js.map')}\n //#sourceURL=${origin}`
|
|
@@ -1206,13 +1227,11 @@ async function Build() {
|
|
|
1206
1227
|
await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), await Compiler(data, origin))
|
|
1207
1228
|
return
|
|
1208
1229
|
}
|
|
1209
|
-
|
|
1210
|
-
bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
|
|
1211
|
-
}
|
|
1230
|
+
bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
|
|
1212
1231
|
await writer(process.cwd() + "/dist/src/" + name, data);
|
|
1213
1232
|
})
|
|
1214
1233
|
|
|
1215
|
-
const scannedPublicFiles = await glob("
|
|
1234
|
+
const scannedPublicFiles = await glob("**/**.{css,js,html,mjs,cjs}", {
|
|
1216
1235
|
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
1217
1236
|
cwd: process.cwd() + '/public/',
|
|
1218
1237
|
absolute: true,
|
|
@@ -1220,7 +1239,7 @@ async function Build() {
|
|
|
1220
1239
|
scannedPublicFiles.forEach(async (file) => {
|
|
1221
1240
|
file = file.replace(/\\/g, '/');
|
|
1222
1241
|
file = file.split('/public/')[1]
|
|
1223
|
-
let data =
|
|
1242
|
+
let data = await reader(process.cwd() + "/public/" + file)
|
|
1224
1243
|
bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
|
|
1225
1244
|
await writer(process.cwd() + "/dist/public/" + file, data);
|
|
1226
1245
|
})
|
|
@@ -1253,6 +1272,7 @@ async function Build() {
|
|
|
1253
1272
|
}
|
|
1254
1273
|
|
|
1255
1274
|
globalThis.isBuilding = false
|
|
1275
|
+
console.log(`\nTotal bundle size: ${Math.round(bundleSize / 1000)}kb`)
|
|
1256
1276
|
|
|
1257
1277
|
bundleSize = 0;
|
|
1258
1278
|
|
|
@@ -1360,7 +1380,7 @@ switch (true) {
|
|
|
1360
1380
|
globalThis.devMode = true
|
|
1361
1381
|
globalThis.isProduction = false
|
|
1362
1382
|
console.log(`
|
|
1363
|
-
Vader.js
|
|
1383
|
+
Vader.js v1.3.3
|
|
1364
1384
|
- Watching for changes in ./pages
|
|
1365
1385
|
- Watching for changes in ./src
|
|
1366
1386
|
- Watching for changes in ./public
|
|
@@ -1382,7 +1402,6 @@ Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json'
|
|
|
1382
1402
|
})
|
|
1383
1403
|
}
|
|
1384
1404
|
|
|
1385
|
-
console.log('\nRebuilding...')
|
|
1386
1405
|
globalThis.isBuilding = true
|
|
1387
1406
|
Build()
|
|
1388
1407
|
}
|