@@ -265,11 +265,15 @@ export class Appliaction {
265
265
// ensure output dir
266
266
await ensureDir ( distDir )
267
267
268
- // ssg, bundle & optimizing
269
- await this . bundle ( )
268
+ // optimizing
270
269
await this . optimize ( )
270
+
271
+ // ssg
271
272
await this . ssg ( )
272
273
274
+ // copy bundle dist
275
+ await this . copyDist ( )
276
+
273
277
// copy public assets
274
278
const publicDir = path . join ( this . workingDir , 'public' )
275
279
if ( existsDirSync ( publicDir ) ) {
@@ -342,15 +346,15 @@ export class Appliaction {
342
346
private getScripts ( ) {
343
347
const baseUrl = path . join ( this . config . baseUrl , '/_aleph/' )
344
348
const mainModule = this . #modules. get ( '/main.ts' ) !
345
- const depsModule = this . #modules. get ( '/deps.bundling. js' )
346
- const sharedModule = this . #modules. get ( '/shared.bundling. js' )
349
+ const depsModule = this . #modules. get ( '/deps.js' )
350
+ const sharedModule = this . #modules. get ( '/shared.js' )
347
351
const polyfillModule = this . #modules. get ( '/polyfill.js' )
348
352
349
353
return [
350
- polyfillModule ? { src : path . join ( baseUrl , `polyfill.${ util . shortHash ( polyfillModule . sourceHash ) } .js` ) } : { } ,
351
- depsModule ? { src : path . join ( baseUrl , `deps.${ util . shortHash ( depsModule . sourceHash ) } .js` ) , } : { } ,
352
- sharedModule ? { src : path . join ( baseUrl , `shared.${ util . shortHash ( sharedModule . sourceHash ) } .js` ) , } : { } ,
353
- ! this . isDev ? { src : path . join ( baseUrl , `main.${ util . shortHash ( mainModule . sourceHash ) } .js` ) , } : { } ,
354
+ polyfillModule ? { src : path . join ( baseUrl , `polyfill.bundle. ${ util . shortHash ( polyfillModule . hash ) } .js` ) } : { } ,
355
+ depsModule ? { src : path . join ( baseUrl , `deps.bundle. ${ util . shortHash ( depsModule . hash ) } .js` ) , } : { } ,
356
+ sharedModule ? { src : path . join ( baseUrl , `shared.bundle. ${ util . shortHash ( sharedModule . hash ) } .js` ) , } : { } ,
357
+ ! this . isDev ? { src : path . join ( baseUrl , `main.bundle. ${ util . shortHash ( mainModule . hash ) } .js` ) , } : { } ,
354
358
this . isDev ? { src : path . join ( baseUrl , `main.${ util . shortHash ( mainModule . hash ) } .js` ) , type : 'module' } : { } ,
355
359
this . isDev ? { src : path . join ( baseUrl , `-/deno.land/x/aleph/nomodule.js` ) , nomodule : true } : { } ,
356
360
]
@@ -548,6 +552,10 @@ export class Appliaction {
548
552
} )
549
553
}
550
554
555
+ if ( ! this . isDev ) {
556
+ log . info ( "Building..." )
557
+ }
558
+
551
559
// check custom components
552
560
for await ( const { path : p , } of walk ( this . srcDir , { ...walkOptions , maxDepth : 1 , exts : [ ...walkOptions . exts , '.tsx' , '.jsx' ] } ) ) {
553
561
const name = path . basename ( p )
@@ -615,6 +623,8 @@ export class Appliaction {
615
623
616
624
if ( this . isDev ) {
617
625
this . watch ( )
626
+ } else {
627
+ await this . bundle ( )
618
628
}
619
629
}
620
630
@@ -758,7 +768,7 @@ export class Appliaction {
758
768
const sourceCode = [
759
769
( this . config . framework === 'react' && this . isDev ) && `import "${ alephPkgUrl } /framework/react/refresh.ts"` ,
760
770
`import bootstrap from "${ alephPkgUrl } /framework/${ framework } /bootstrap.ts"` ,
761
- `bootstrap(${ JSON . stringify ( config , undefined , 4 ) } )`
771
+ `bootstrap(${ JSON . stringify ( config , undefined , this . isDev ? 4 : undefined ) } )`
762
772
] . filter ( Boolean ) . join ( '\n' )
763
773
await this . compile ( '/main.ts' , { sourceCode } )
764
774
if ( ! this . isDev ) {
@@ -1283,21 +1293,18 @@ export class Appliaction {
1283
1293
const lookup = ( url : string ) => {
1284
1294
if ( this . #modules. has ( url ) ) {
1285
1295
const { deps } = this . #modules. get ( url ) !
1286
- deps . forEach ( ( { url } ) => {
1287
- if ( ! refCounter . has ( url ) ) {
1288
- refCounter . set ( url , 1 )
1289
- } else {
1296
+ new Set ( deps . map ( ( { url } ) => url ) ) . forEach ( url => {
1297
+ if ( refCounter . has ( url ) ) {
1290
1298
refCounter . set ( url , refCounter . get ( url ) ! + 1 )
1299
+ } else {
1300
+ refCounter . set ( url , 1 )
1291
1301
}
1292
1302
} )
1293
1303
}
1294
1304
}
1295
- const appModule = Array . from ( this . #modules. keys ( ) )
1296
- . filter ( url => trimPageModuleExt ( url ) === '/app' )
1297
- . map ( url => this . #modules. get ( url ) ) [ 0 ]
1298
- const e404Module = Array . from ( this . #modules. keys ( ) )
1299
- . filter ( url => trimPageModuleExt ( url ) === '/404' )
1300
- . map ( url => this . #modules. get ( url ) ) [ 0 ]
1305
+ const mods = Array . from ( this . #modules. values ( ) )
1306
+ const appModule = mods . find ( ( { url } ) => trimPageModuleExt ( url ) == '/app' )
1307
+ const e404Module = mods . find ( ( { url } ) => trimPageModuleExt ( url ) == '/404' )
1301
1308
const pageModules : Module [ ] = [ ]
1302
1309
1303
1310
lookup ( '/main.ts' )
@@ -1322,6 +1329,8 @@ export class Appliaction {
1322
1329
}
1323
1330
} ) )
1324
1331
1332
+ log . debug ( refCounter )
1333
+
1325
1334
const remoteDeps : string [ ] = [ ]
1326
1335
const localSharedDeps : string [ ] = [ ]
1327
1336
Array . from ( refCounter . entries ( ) ) . forEach ( ( [ url , count ] ) => {
@@ -1338,95 +1347,78 @@ export class Appliaction {
1338
1347
localSharedDeps . push ( e404Module . url )
1339
1348
}
1340
1349
1341
- log . info ( '- Bundle ' )
1350
+ log . info ( '- Bundling ' )
1342
1351
await this . createChunkBundle ( 'deps' , remoteDeps )
1343
1352
if ( localSharedDeps . length > 0 ) {
1344
1353
await this . createChunkBundle ( 'shared' , localSharedDeps )
1345
1354
}
1346
1355
1347
- // copy main module
1348
- const mainModule = this . getModule ( '/main.ts' ) !
1349
- const mainJSFile = path . join ( this . outputDir , '_aleph' , `main.${ util . shortHash ( mainModule . sourceHash ) } .js` )
1350
- const mainJSConent = await Deno . readTextFile ( mainModule . bundlingFile )
1351
- await Deno . writeTextFile ( mainJSFile , mainJSConent )
1352
-
1353
1356
// create and copy polyfill
1354
- const polyfillMode = this . newModule ( '/polyfill.js' )
1357
+ const polyfillMod = this . newModule ( '/polyfill.js' )
1355
1358
const hash = ( new Sha1 ) . update ( buildChecksum ) . update ( AlephRuntimeCode ) . update ( `${ this . config . buildTarget } -${ VERSION } ` ) . hex ( )
1356
- const polyfillFile = path . join ( this . buildDir , `polyfill.${ util . shortHash ( hash ) } .js` )
1359
+ const polyfillFile = path . join ( this . buildDir , `polyfill.bundle. ${ util . shortHash ( hash ) } .js` )
1357
1360
if ( ! existsFileSync ( polyfillFile ) ) {
1358
1361
const rawPolyfillFile = `${ alephPkgUrl } /compiler/polyfills/${ this . config . buildTarget } /polyfill.js`
1359
1362
await this . runDenoBundle ( rawPolyfillFile , polyfillFile , AlephRuntimeCode , true )
1360
1363
}
1361
- await Deno . copyFile ( polyfillFile , path . join ( this . outputDir , '_aleph' , `polyfill.${ util . shortHash ( hash ) } .js` ) )
1362
-
1363
- polyfillMode . hash = polyfillMode . sourceHash = hash
1364
- this . #modules. set ( polyfillMode . url , polyfillMode )
1364
+ polyfillMod . hash = polyfillMod . sourceHash = hash
1365
+ this . #modules. set ( polyfillMod . url , polyfillMod )
1366
+ log . info ( ` {} polyfill (${ this . config . buildTarget . toUpperCase ( ) } ) ${ colors . dim ( '• ' + util . formatBytes ( Deno . statSync ( polyfillFile ) . size ) ) } ` )
1365
1367
1366
1368
// bundle and copy page moudles
1367
1369
await Promise . all ( pageModules . map ( async mod => this . createPageBundle ( mod , localSharedDeps ) ) )
1370
+
1371
+ // create main.bundle.xxxxxxxxx.js
1372
+ const mainModule = this . getModule ( '/main.ts' ) !
1373
+ const bundleFile = path . join ( this . buildDir , `main.bundle.${ util . shortHash ( mainModule . hash ) } .js` )
1374
+ await Deno . copyFile ( mainModule . bundlingFile , bundleFile )
1368
1375
}
1369
1376
1370
1377
/** create chunk bundle. */
1371
- private async createChunkBundle ( name : string , list : string [ ] , header = '' ) {
1372
- const imports = list . map ( ( url , i ) => {
1378
+ private async createChunkBundle ( name : string , list : string [ ] ) {
1379
+ const bundlingCode = list . map ( ( url , i ) => {
1373
1380
const mod = this . #modules. get ( url )
1374
1381
if ( mod ) {
1375
- return [
1376
- `import * as ${ name } _mod_${ i } from ${ JSON . stringify ( util . isLikelyHttpURL ( mod . url ) ? mod . jsFile : mod . bundlingFile ) } ` ,
1382
+ const importUrl = util . isLikelyHttpURL ( mod . url ) ? mod . jsFile : mod . bundlingFile
1383
+ return importUrl ? [
1384
+ `import * as ${ name } _mod_${ i } from ${ JSON . stringify ( importUrl ) } ` ,
1377
1385
`__ALEPH.pack[${ JSON . stringify ( url ) } ] = ${ name } _mod_${ i } `
1378
- ]
1386
+ ] : [ ]
1379
1387
}
1380
1388
} ) . flat ( ) . join ( '\n' )
1381
- const bundlingCode = imports
1382
- const mod = this . newModule ( `/${ name } .bundling.js` )
1383
- const hash = ( new Sha1 ) . update ( buildChecksum ) . update ( header ) . update ( bundlingCode ) . hex ( )
1389
+ const mod = this . newModule ( `/${ name } .js` )
1390
+ const hash = ( new Sha1 ) . update ( buildChecksum ) . update ( bundlingCode ) . hex ( )
1384
1391
const bundlingFile = path . join ( this . buildDir , mod . url )
1385
1392
const bundleFile = path . join ( this . buildDir , `${ name } .bundle.${ util . shortHash ( hash ) } .js` )
1386
- const saveAs = path . join ( this . outputDir , `_aleph/${ name } .${ util . shortHash ( hash ) } .js` )
1387
-
1388
- mod . hash = mod . sourceHash = hash
1389
1393
1390
- if ( existsFileSync ( bundleFile ) ) {
1391
- this . #modules. set ( mod . url , mod )
1392
- await Deno . rename ( bundleFile , saveAs )
1393
- return
1394
- }
1395
-
1396
- await Deno . writeTextFile ( bundlingFile , bundlingCode )
1397
- const n = await this . runDenoBundle ( bundlingFile , bundleFile , header )
1398
- if ( n > 0 ) {
1399
- log . info ( ` {} ${ name } .js ${ colors . dim ( '• ' + util . formatBytes ( n ) ) } ` )
1394
+ if ( ! existsFileSync ( bundleFile ) ) {
1395
+ await Deno . writeTextFile ( bundlingFile , bundlingCode )
1396
+ await this . runDenoBundle ( bundlingFile , bundleFile )
1397
+ Deno . remove ( bundlingFile )
1400
1398
}
1401
1399
1400
+ mod . hash = mod . sourceHash = hash
1402
1401
this . #modules. set ( mod . url , mod )
1403
- await Deno . rename ( bundleFile , saveAs )
1404
- Deno . remove ( bundlingFile )
1402
+
1403
+ log . info ( ` {} ${ name } ${ colors . dim ( '• ' + util . formatBytes ( Deno . statSync ( bundleFile ) . size ) ) } ` )
1405
1404
}
1406
1405
1407
1406
/** create page bundle. */
1408
- private async createPageBundle ( mod : Module , bundledModules : string [ ] , header = '' ) {
1407
+ private async createPageBundle ( mod : Module , bundledModules : string [ ] ) {
1409
1408
const { bundlingFile, hash } = await this . compile ( mod . url , { bundleMode : true , bundledModules } )
1410
1409
const _tmp = util . trimSuffix ( bundlingFile . replace ( reHashJs , '' ) , '.bundling' )
1411
1410
const _bundlingFile = _tmp + `.bundling.js`
1412
1411
const bundleFile = _tmp + `.bundle.${ util . shortHash ( hash ) } .js`
1413
- const saveAs = path . join ( this . outputDir , `/_aleph/` , util . trimPrefix ( _tmp , this . buildDir ) + `.${ util . shortHash ( hash ) } .js` )
1414
1412
1415
- if ( existsFileSync ( bundleFile ) ) {
1416
- await ensureDir ( path . dirname ( saveAs ) )
1417
- await Deno . rename ( bundleFile , saveAs )
1418
- return
1413
+ if ( ! existsFileSync ( bundleFile ) ) {
1414
+ const bundlingCode = [
1415
+ `import * as mod from ${ JSON . stringify ( bundlingFile ) } ` ,
1416
+ `__ALEPH.pack[${ JSON . stringify ( mod . url ) } ] = mod`
1417
+ ] . join ( '\n' )
1418
+ await Deno . writeTextFile ( _bundlingFile , bundlingCode )
1419
+ await this . runDenoBundle ( _bundlingFile , bundleFile )
1420
+ Deno . remove ( _bundlingFile )
1419
1421
}
1420
-
1421
- const bundlingCode = [
1422
- `import * as mod from ${ JSON . stringify ( bundlingFile ) } ` ,
1423
- `__ALEPH.pack[${ JSON . stringify ( mod . url ) } ] = mod`
1424
- ] . join ( '\n' )
1425
- await Deno . writeTextFile ( _bundlingFile , bundlingCode )
1426
- await this . runDenoBundle ( _bundlingFile , bundleFile , header )
1427
- await ensureDir ( path . dirname ( saveAs ) )
1428
- await Deno . rename ( bundleFile , saveAs )
1429
- Deno . remove ( _bundlingFile )
1430
1422
}
1431
1423
1432
1424
/** run deno bundle and compess the output with terser. */
@@ -1478,7 +1470,43 @@ export class Appliaction {
1478
1470
1479
1471
await cleanupCompilation ( bundleFile )
1480
1472
await Deno . writeTextFile ( bundleFile , code )
1481
- return code . length
1473
+ }
1474
+
1475
+ private async copyDist ( ) {
1476
+ const pageModules : Module [ ] = [ ]
1477
+ this . #pageRouting. lookup ( routes => routes . forEach ( ( { module : { url } } ) => {
1478
+ const mod = this . getModule ( url )
1479
+ if ( mod ) {
1480
+ pageModules . push ( mod )
1481
+ }
1482
+ } ) )
1483
+
1484
+ await Promise . all ( [
1485
+ ( async ( ) => {
1486
+ const mainModule = this . getModule ( '/main.ts' ) !
1487
+ const filename = `main.bundle.${ util . shortHash ( mainModule . hash ) } .js`
1488
+ const bundleFile = path . join ( this . buildDir , filename )
1489
+ const saveAs = path . join ( this . outputDir , '_aleph' , filename )
1490
+ await Deno . copyFile ( bundleFile , saveAs )
1491
+ } ) ( ) ,
1492
+ ...[ 'deps' , 'shared' , 'polyfill' ] . map ( async name => {
1493
+ const mod = this . #modules. get ( `/${ name } .js` )
1494
+ if ( mod ) {
1495
+ const { hash } = mod
1496
+ const bundleFile = path . join ( this . buildDir , `${ name } .bundle.${ util . shortHash ( hash ) } .js` )
1497
+ const saveAs = path . join ( this . outputDir , '_aleph' , `${ name } .bundle.${ util . shortHash ( hash ) } .js` )
1498
+ await Deno . copyFile ( bundleFile , saveAs )
1499
+ }
1500
+ } ) ,
1501
+ ...pageModules . map ( async mod => {
1502
+ const { bundlingFile, hash } = mod
1503
+ const _tmp = util . trimSuffix ( bundlingFile . replace ( reHashJs , '' ) , '.bundling' )
1504
+ const bundleFile = _tmp + `.bundle.${ util . shortHash ( hash ) } .js`
1505
+ const saveAs = path . join ( this . outputDir , `/_aleph/` , util . trimPrefix ( _tmp , this . buildDir ) + `.bundle.${ util . shortHash ( hash ) } .js` )
1506
+ await ensureDir ( path . dirname ( saveAs ) )
1507
+ await Deno . copyFile ( bundleFile , saveAs )
1508
+ } )
1509
+ ] )
1482
1510
}
1483
1511
1484
1512
/** optimize for production. */
@@ -1606,7 +1634,9 @@ export class Appliaction {
1606
1634
ret . body = `<div id="__aleph">${ body } </div>`
1607
1635
ret . data = data
1608
1636
this . #renderCache. get ( url . pagePath ) ! . set ( key , ret )
1609
- log . info ( `render '${ url . pathname } ' in ${ Math . round ( performance . now ( ) - start ) } ms` )
1637
+ if ( this . isDev ) {
1638
+ log . info ( `render '${ url . pathname } ' in ${ Math . round ( performance . now ( ) - start ) } ms` )
1639
+ }
1610
1640
} catch ( err ) {
1611
1641
ret . status = 500
1612
1642
ret . head = [ '<title>Error 500 - Aleph.js</title>' ]
0 commit comments