5
5
TRACE_IGNORES ,
6
6
type BuildTraceContext ,
7
7
getFilesMapFromReasons ,
8
+ getHash ,
8
9
} from './webpack/plugins/next-trace-entrypoints-plugin'
9
10
10
11
import {
@@ -29,6 +30,8 @@ import type { RoutesUsingEdgeRuntime } from './utils'
29
30
30
31
const debug = debugOriginal ( 'next:build:build-traces' )
31
32
33
+ const hashCache : Record < string , string > = { }
34
+
32
35
function shouldIgnore (
33
36
file : string ,
34
37
serverIgnoreFn : ( file : string ) => boolean ,
@@ -88,11 +91,13 @@ export async function collectBuildTraces({
88
91
hasSsrAmpPages,
89
92
buildTraceContext,
90
93
outputFileTracingRoot,
94
+ isFlyingShuttle,
91
95
} : {
92
96
dir : string
93
97
distDir : string
94
98
staticPages : string [ ]
95
99
hasSsrAmpPages : boolean
100
+ isFlyingShuttle ?: boolean
96
101
outputFileTracingRoot : string
97
102
// pageInfos is serialized when this function runs in a worker.
98
103
edgeRuntimeRoutes : RoutesUsingEdgeRuntime
@@ -496,9 +501,11 @@ export async function collectBuildTraces({
496
501
[ minimalServerEntries , minimalServerTracedFiles ] ,
497
502
] as Array < [ string [ ] , Set < string > ] > ) {
498
503
for ( const file of entries ) {
499
- const curFiles = parentFilesMap . get (
500
- path . relative ( outputFileTracingRoot , file )
501
- )
504
+ const curFiles = [
505
+ ...( parentFilesMap
506
+ . get ( path . relative ( outputFileTracingRoot , file ) )
507
+ ?. keys ( ) || [ ] ) ,
508
+ ]
502
509
tracedFiles . add ( path . relative ( distDir , file ) . replace ( / \\ / g, '/' ) )
503
510
504
511
for ( const curFile of curFiles || [ ] ) {
@@ -545,8 +552,10 @@ export async function collectBuildTraces({
545
552
}
546
553
547
554
// we don't need to trace for automatically statically optimized
548
- // pages as they don't have server bundles
549
- if ( staticPages . includes ( route ) ) {
555
+ // pages as they don't have server bundles, note there is
556
+ // the caveat with flying shuttle mode as it needs this for
557
+ // detecting changed entries
558
+ if ( staticPages . includes ( route ) && ! isFlyingShuttle ) {
550
559
return
551
560
}
552
561
const entryOutputPath = path . join (
@@ -557,14 +566,22 @@ export async function collectBuildTraces({
557
566
const traceOutputPath = `${ entryOutputPath } .nft.json`
558
567
const existingTrace = JSON . parse (
559
568
await fs . readFile ( traceOutputPath , 'utf8' )
560
- )
569
+ ) as {
570
+ version : number
571
+ files : string [ ]
572
+ fileHashes : Record < string , string >
573
+ }
561
574
const traceOutputDir = path . dirname ( traceOutputPath )
562
575
const curTracedFiles = new Set < string > ( )
576
+ const curFileHashes : Record < string , string > =
577
+ existingTrace . fileHashes
563
578
564
579
for ( const file of [ ...entryNameFiles , entryOutputPath ] ) {
565
- const curFiles = parentFilesMap . get (
566
- path . relative ( outputFileTracingRoot , file )
567
- )
580
+ const curFiles = [
581
+ ...( parentFilesMap
582
+ . get ( path . relative ( outputFileTracingRoot , file ) )
583
+ ?. keys ( ) || [ ] ) ,
584
+ ]
568
585
for ( const curFile of curFiles || [ ] ) {
569
586
if (
570
587
! shouldIgnore (
@@ -579,6 +596,19 @@ export async function collectBuildTraces({
579
596
. relative ( traceOutputDir , filePath )
580
597
. replace ( / \\ / g, '/' )
581
598
curTracedFiles . add ( outputFile )
599
+
600
+ if ( isFlyingShuttle ) {
601
+ try {
602
+ let hash = hashCache [ filePath ]
603
+
604
+ if ( ! hash ) {
605
+ hash = getHash ( await fs . readFile ( filePath ) )
606
+ }
607
+ curFileHashes [ outputFile ] = hash
608
+ } catch ( err : any ) {
609
+ // handle symlink errors or similar
610
+ }
611
+ }
582
612
}
583
613
}
584
614
}
@@ -592,6 +622,11 @@ export async function collectBuildTraces({
592
622
JSON . stringify ( {
593
623
...existingTrace ,
594
624
files : [ ...curTracedFiles ] . sort ( ) ,
625
+ ...( isFlyingShuttle
626
+ ? {
627
+ fileHashes : curFileHashes ,
628
+ }
629
+ : { } ) ,
595
630
} )
596
631
)
597
632
} )
0 commit comments