@@ -345,9 +345,9 @@ export class Aleph implements IAleph {
345
345
e . emit ( 'modify-' + module . specifier , { refreshPage : refreshPage || undefined } )
346
346
} )
347
347
}
348
- this . applyCompilationSideEffect ( module , ( { specifier } ) => {
348
+ this . applyCompilationSideEffect ( module , ( { specifier, hash } ) => {
349
349
if ( ! hmrable && this . isHMRable ( specifier ) ) {
350
- log . debug ( ' compilation side-effect:' , specifier , dim ( '<-' ) , module . specifier )
350
+ log . debug ( ` compilation side-effect: ${ specifier } ( ${ hash ?. substr ( 0 , 6 ) } ) ${ dim ( '<-' ) } ${ module . specifier } ( ${ module . hash ?. substr ( 0 , 6 ) } )` )
351
351
this . #fsWatchListeners. forEach ( e => {
352
352
e . emit ( 'modify-' + specifier , { refreshPage : refreshPage || undefined } )
353
353
} )
@@ -895,7 +895,7 @@ export class Aleph implements IAleph {
895
895
return await import ( `file://${ join ( this . buildDir , jsFile ) } #${ ( hash || sourceHash ) . slice ( 0 , 6 ) } ` )
896
896
}
897
897
898
- async readModuleJS ( module : Module ) : Promise < Uint8Array | null > {
898
+ async readModuleJS ( module : Module , injectHMRCode = false ) : Promise < Uint8Array | null > {
899
899
const { specifier, jsFile, jsBuffer } = module
900
900
if ( ! jsBuffer ) {
901
901
const cacheFp = join ( this . buildDir , jsFile )
@@ -905,8 +905,12 @@ export class Aleph implements IAleph {
905
905
}
906
906
}
907
907
908
- if ( ! this . isDev || ! this . isHMRable ( specifier ) || ! module . jsBuffer ) {
909
- return module . jsBuffer || null
908
+ if ( ! module . jsBuffer ) {
909
+ return null
910
+ }
911
+
912
+ if ( ! injectHMRCode || ! this . isHMRable ( specifier ) ) {
913
+ return module . jsBuffer
910
914
}
911
915
912
916
let code = new TextDecoder ( ) . decode ( module . jsBuffer )
@@ -915,16 +919,17 @@ export class Aleph implements IAleph {
915
919
code = ( module as any ) . csrCode
916
920
} else {
917
921
const { code : csrCode } = await stripSsrCode ( specifier , code , { sourceMap : true , swcOptions : { sourceType : SourceType . JS } } )
922
+ // cache csr code
918
923
Object . assign ( module , { csrCode } )
919
- // todo: merge source map
920
924
code = csrCode
925
+ // todo: merge source map
921
926
}
922
927
}
923
928
this . #transformListeners. forEach ( ( { test, transform } ) => {
924
929
if ( test === 'hmr' ) {
925
930
const ret = transform ( { specifier, code } )
926
- // todo: merge source map
927
931
code = ret . code
932
+ // todo: merge source map
928
933
}
929
934
} )
930
935
return new TextEncoder ( ) . encode ( [
@@ -1239,10 +1244,6 @@ export class Aleph implements IAleph {
1239
1244
] )
1240
1245
}
1241
1246
1242
- if ( ignoreDeps ) {
1243
- return
1244
- }
1245
-
1246
1247
if ( module . deps . length > 0 ) {
1247
1248
let fsync = false
1248
1249
const encoder = new TextEncoder ( )
@@ -1252,49 +1253,54 @@ export class Aleph implements IAleph {
1252
1253
await this . readModuleJS ( module )
1253
1254
}
1254
1255
await Promise . all ( module . deps . map ( async ( { specifier, hashLoc } ) => {
1255
- const [ depModule , depSource ] = await this . initModule ( specifier , { externalRemoteDeps } )
1256
- if ( ! depModule . external ) {
1257
- await this . transpileModule ( depModule , depSource , false , __tracing )
1256
+ let depModule : Module | null
1257
+ if ( ignoreDeps ) {
1258
+ depModule = this . getModule ( specifier )
1259
+ } else {
1260
+ const [ mod , src ] = await this . initModule ( specifier , { externalRemoteDeps } )
1261
+ if ( ! mod . external ) {
1262
+ await this . transpileModule ( mod , src , false , __tracing )
1263
+ }
1264
+ depModule = mod
1258
1265
}
1259
- const hash = depModule . hash || depModule . sourceHash
1260
- if ( hashLoc !== undefined ) {
1261
- const { jsBuffer } = module
1262
- const hashData = encoder . encode ( ( hash ) . substr ( 0 , 6 ) )
1263
- if ( jsBuffer && ! equals ( hashData , jsBuffer . slice ( hashLoc , hashLoc + 6 ) ) ) {
1264
- copy ( hashData , jsBuffer , hashLoc )
1265
- if ( ! fsync ) {
1266
+ if ( depModule ) {
1267
+ const hash = depModule . hash || depModule . sourceHash
1268
+ if ( hashLoc !== undefined ) {
1269
+ if ( await this . replaceDepHash ( module , hashLoc , hash ) ) {
1266
1270
fsync = true
1267
1271
}
1268
1272
}
1273
+ hasher . update ( hash )
1274
+ } else {
1275
+ log . error ( `transpile '${ module . specifier } ': missing dependency module '${ specifier } '` )
1269
1276
}
1270
- hasher . update ( hash )
1271
1277
} ) )
1272
1278
module . hash = hasher . toString ( )
1273
1279
if ( fsync ) {
1274
- await this . cacheModule ( module )
1280
+ await this . writeModule ( module )
1275
1281
}
1276
1282
} else {
1277
1283
module . hash = module . sourceHash
1278
1284
}
1279
1285
}
1280
1286
1281
1287
/** apply compilation side-effect caused by updating dependency graph. */
1282
- private async applyCompilationSideEffect ( by : Module , callback : ( mod : Module ) => void ) {
1288
+ private async applyCompilationSideEffect ( by : Module , callback : ( mod : Module ) => void , __tracing = new Set < string > ( ) ) {
1289
+ if ( __tracing . has ( by . specifier ) ) {
1290
+ return
1291
+ }
1292
+ __tracing . add ( by . specifier )
1293
+
1283
1294
const hash = by . hash || by . sourceHash
1284
- const hashData = ( new TextEncoder ( ) ) . encode ( hash . substr ( 0 , 6 ) )
1285
1295
for ( const mod of this . #modules. values ( ) ) {
1286
1296
const { deps } = mod
1287
1297
if ( deps . length > 0 ) {
1288
1298
let fsync = false
1289
1299
for ( const dep of deps ) {
1290
1300
const { specifier, hashLoc } = dep
1291
1301
if ( specifier === by . specifier && hashLoc !== undefined ) {
1292
- const jsCode = await this . readModuleJS ( mod )
1293
- if ( jsCode && ! equals ( hashData , jsCode . slice ( hashLoc , hashLoc + 6 ) ) ) {
1294
- copy ( hashData , jsCode , hashLoc )
1295
- if ( ! fsync ) {
1296
- fsync = true
1297
- }
1302
+ if ( await this . replaceDepHash ( mod , hashLoc , hash ) ) {
1303
+ fsync = true
1298
1304
}
1299
1305
}
1300
1306
}
@@ -1307,14 +1313,28 @@ export class Aleph implements IAleph {
1307
1313
}
1308
1314
} )
1309
1315
mod . hash = hasher . toString ( )
1310
- await this . cacheModule ( mod )
1311
1316
callback ( mod )
1312
- await this . applyCompilationSideEffect ( mod , callback )
1317
+ this . applyCompilationSideEffect ( mod , callback )
1318
+ this . writeModule ( mod )
1313
1319
}
1314
1320
}
1315
1321
}
1316
1322
}
1317
1323
1324
+ /** replace dep hash in the `jsBuffer` and remove `csrCode` cache if it exits */
1325
+ private async replaceDepHash ( module : Module , hashLoc : number , hash : string ) {
1326
+ const hashData = ( new TextEncoder ( ) ) . encode ( hash . substr ( 0 , 6 ) )
1327
+ await this . readModuleJS ( module )
1328
+ if ( module . jsBuffer && ! equals ( hashData , module . jsBuffer . slice ( hashLoc , hashLoc + 6 ) ) ) {
1329
+ copy ( hashData , module . jsBuffer , hashLoc )
1330
+ if ( 'csrCode' in module ) {
1331
+ Reflect . deleteProperty ( module , 'csrCode' )
1332
+ }
1333
+ return true
1334
+ }
1335
+ return false
1336
+ }
1337
+
1318
1338
private clearSSRCache ( specifier : string ) {
1319
1339
if ( trimBuiltinModuleExts ( specifier ) === '/app' ) {
1320
1340
this . #renderer. clearCache ( )
@@ -1324,7 +1344,7 @@ export class Aleph implements IAleph {
1324
1344
}
1325
1345
}
1326
1346
1327
- private async cacheModule ( module : Module ) {
1347
+ private async writeModule ( module : Module ) {
1328
1348
const { specifier, jsBuffer, jsFile } = module
1329
1349
if ( jsBuffer ) {
1330
1350
const cacheFp = join ( this . buildDir , jsFile )
0 commit comments