@@ -5,14 +5,15 @@ import type { PagesManifest } from './webpack/plugins/pages-manifest-plugin'
5
5
import type { ExportPathMap , NextConfigComplete } from '../server/config-shared'
6
6
import type { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
7
7
import type { ActionManifest } from './webpack/plugins/flight-client-entry-plugin'
8
- import type { ExportOptions } from '../export'
8
+ import type { ExportAppOptions , ExportAppWorker } from '../export/types '
9
9
10
10
import '../lib/setup-exception-listeners'
11
+
11
12
import { loadEnvConfig } from '@next/env'
12
13
import chalk from 'next/dist/compiled/chalk'
13
14
import crypto from 'crypto'
14
15
import { isMatch , makeRe } from 'next/dist/compiled/micromatch'
15
- import { promises as fs , existsSync as fsExistsSync } from 'fs'
16
+ import fs from 'fs/promises '
16
17
import os from 'os'
17
18
import { Worker } from '../lib/worker'
18
19
import { defaultConfig } from '../server/config-shared'
@@ -151,21 +152,29 @@ import { defaultOverrides } from '../server/require-hook'
151
152
import { initialize as initializeIncrementalCache } from '../server/lib/incremental-cache-server'
152
153
import { nodeFs } from '../server/lib/node-fs-methods'
153
154
154
- export type SsgRoute = {
155
+ interface ExperimentalBypassForInfo {
156
+ experimentalBypassFor ?: RouteHas [ ]
157
+ }
158
+
159
+ interface DataRouteRouteInfo {
160
+ dataRoute : string | null
161
+ }
162
+
163
+ export interface SsgRoute
164
+ extends ExperimentalBypassForInfo ,
165
+ DataRouteRouteInfo {
155
166
initialRevalidateSeconds : number | false
156
167
srcRoute : string | null
157
- dataRoute : string | null
158
168
initialStatus ?: number
159
169
initialHeaders ?: Record < string , string >
160
- experimentalBypassFor ?: RouteHas [ ]
161
170
}
162
171
163
- export type DynamicSsgRoute = {
172
+ export interface DynamicSsgRoute
173
+ extends ExperimentalBypassForInfo ,
174
+ DataRouteRouteInfo {
164
175
routeRegex : string
165
176
fallback : string | null | false
166
- dataRoute : string | null
167
177
dataRouteRegex : string | null
168
- experimentalBypassFor ?: RouteHas [ ]
169
178
}
170
179
171
180
export type PrerenderManifest = {
@@ -2489,15 +2498,10 @@ export default async function build(
2489
2498
ssgPages ,
2490
2499
additionalSsgPaths
2491
2500
)
2492
- const exportApp : typeof import ( '../export' ) . default =
2493
- require ( '../export' ) . default
2501
+ const exportApp : ExportAppWorker = require ( '../export' ) . default
2494
2502
2495
2503
const exportConfig : NextConfigComplete = {
2496
2504
...config ,
2497
- initialPageRevalidationMap : { } ,
2498
- initialPageMetaMap : { } ,
2499
- pageDurationMap : { } ,
2500
- ssgNotFoundPaths : [ ] as string [ ] ,
2501
2505
// Default map will be the collection of automatic statically exported
2502
2506
// pages and incremental pages.
2503
2507
// n.b. we cannot handle this above in combinedPages because the dynamic
@@ -2619,7 +2623,7 @@ export default async function build(
2619
2623
} ,
2620
2624
}
2621
2625
2622
- const exportOptions : ExportOptions = {
2626
+ const exportOptions : ExportAppOptions = {
2623
2627
isInvokedFromCli : false ,
2624
2628
nextConfig : exportConfig ,
2625
2629
hasAppDir,
@@ -2644,10 +2648,17 @@ export default async function build(
2644
2648
: undefined ,
2645
2649
}
2646
2650
2647
- await exportApp ( dir , exportOptions , nextBuildSpan )
2651
+ const exportResult = await exportApp (
2652
+ dir ,
2653
+ exportOptions ,
2654
+ nextBuildSpan
2655
+ )
2656
+
2657
+ // If there was no result, there's nothing more to do.
2658
+ if ( ! exportResult ) return
2648
2659
2649
2660
const postBuildSpinner = createSpinner ( 'Finalizing page optimization' )
2650
- ssgNotFoundPaths = exportConfig . ssgNotFoundPaths
2661
+ ssgNotFoundPaths = exportResult . ssgNotFoundPaths
2651
2662
2652
2663
// remove server bundles that were exported
2653
2664
for ( const page of staticPages ) {
@@ -2659,8 +2670,7 @@ export default async function build(
2659
2670
const page = appNormalizedPaths . get ( originalAppPath ) || ''
2660
2671
const appConfig = appDefaultConfigs . get ( originalAppPath ) || { }
2661
2672
let hasDynamicData =
2662
- appConfig . revalidate === 0 ||
2663
- exportConfig . initialPageRevalidationMap [ page ] === 0
2673
+ appConfig . revalidate === 0 || exportResult . revalidate [ page ] === 0
2664
2674
2665
2675
if ( hasDynamicData && pageInfos . get ( page ) ?. static ) {
2666
2676
// if the page was marked as being static, but it contains dynamic data
@@ -2689,7 +2699,7 @@ export default async function build(
2689
2699
if ( isDynamicRoute ( page ) && route === page ) return
2690
2700
if ( route === '/_not-found' ) return
2691
2701
2692
- let revalidate = exportConfig . initialPageRevalidationMap [ route ]
2702
+ let revalidate = exportResult . revalidate [ page ]
2693
2703
2694
2704
if ( typeof revalidate === 'undefined' ) {
2695
2705
revalidate =
@@ -2714,15 +2724,13 @@ export default async function build(
2714
2724
2715
2725
const routeMeta : Partial < SsgRoute > = { }
2716
2726
2717
- const exportRouteMeta : {
2718
- status ?: number
2719
- headers ?: Record < string , string >
2720
- } = exportConfig . initialPageMetaMap [ route ] || { }
2727
+ const metadata = exportResult . metadata [ route ] ?? { }
2721
2728
2722
- if ( exportRouteMeta . status !== 200 ) {
2723
- routeMeta . initialStatus = exportRouteMeta . status
2729
+ if ( metadata . status !== 200 ) {
2730
+ routeMeta . initialStatus = metadata . status
2724
2731
}
2725
- const exportHeaders = exportRouteMeta . headers
2732
+
2733
+ const exportHeaders = metadata . headers
2726
2734
const headerKeys = Object . keys ( exportHeaders || { } )
2727
2735
2728
2736
if ( exportHeaders && headerKeys . length ) {
@@ -2956,7 +2964,7 @@ export default async function build(
2956
2964
const file = normalizePagePath ( page )
2957
2965
2958
2966
const pageInfo = pageInfos . get ( page )
2959
- const durationInfo = exportConfig . pageDurationMap [ page ]
2967
+ const durationInfo = exportResult . durations [ page ]
2960
2968
if ( pageInfo && durationInfo ) {
2961
2969
// Set Build Duration
2962
2970
if ( pageInfo . ssgPageRoutes ) {
@@ -2996,9 +3004,14 @@ export default async function build(
2996
3004
for ( const locale of i18n . locales ) {
2997
3005
const localePage = `/${ locale } ${ page === '/' ? '' : page } `
2998
3006
3007
+ const initialRevalidateSeconds =
3008
+ exportResult . revalidate [ localePage ]
3009
+ if ( typeof initialRevalidateSeconds === 'undefined' ) {
3010
+ throw new Error ( "Invariant: locale page wasn't built" )
3011
+ }
3012
+
2999
3013
finalPrerenderRoutes [ localePage ] = {
3000
- initialRevalidateSeconds :
3001
- exportConfig . initialPageRevalidationMap [ localePage ] ,
3014
+ initialRevalidateSeconds,
3002
3015
srcRoute : null ,
3003
3016
dataRoute : path . posix . join (
3004
3017
'/_next/data' ,
@@ -3008,9 +3021,13 @@ export default async function build(
3008
3021
}
3009
3022
}
3010
3023
} else {
3024
+ const initialRevalidateSeconds = exportResult . revalidate [ page ]
3025
+ if ( typeof initialRevalidateSeconds === 'undefined' ) {
3026
+ throw new Error ( "Invariant: page wasn't built" )
3027
+ }
3028
+
3011
3029
finalPrerenderRoutes [ page ] = {
3012
- initialRevalidateSeconds :
3013
- exportConfig . initialPageRevalidationMap [ page ] ,
3030
+ initialRevalidateSeconds,
3014
3031
srcRoute : null ,
3015
3032
dataRoute : path . posix . join (
3016
3033
'/_next/data' ,
@@ -3021,8 +3038,12 @@ export default async function build(
3021
3038
}
3022
3039
// Set Page Revalidation Interval
3023
3040
if ( pageInfo ) {
3024
- pageInfo . initialRevalidateSeconds =
3025
- exportConfig . initialPageRevalidationMap [ page ]
3041
+ const initialRevalidateSeconds = exportResult . revalidate [ page ]
3042
+ if ( typeof initialRevalidateSeconds === 'undefined' ) {
3043
+ throw new Error ( "Invariant: page wasn't built" )
3044
+ }
3045
+
3046
+ pageInfo . initialRevalidateSeconds = initialRevalidateSeconds
3026
3047
}
3027
3048
} else {
3028
3049
// For a dynamic SSG page, we did not copy its data exports and only
@@ -3069,9 +3090,14 @@ export default async function build(
3069
3090
)
3070
3091
}
3071
3092
3093
+ const initialRevalidateSeconds =
3094
+ exportResult . revalidate [ route ]
3095
+ if ( typeof initialRevalidateSeconds === 'undefined' ) {
3096
+ throw new Error ( "Invariant: page wasn't built" )
3097
+ }
3098
+
3072
3099
finalPrerenderRoutes [ route ] = {
3073
- initialRevalidateSeconds :
3074
- exportConfig . initialPageRevalidationMap [ route ] ,
3100
+ initialRevalidateSeconds,
3075
3101
srcRoute : page ,
3076
3102
dataRoute : path . posix . join (
3077
3103
'/_next/data' ,
@@ -3082,8 +3108,7 @@ export default async function build(
3082
3108
3083
3109
// Set route Revalidation Interval
3084
3110
if ( pageInfo ) {
3085
- pageInfo . initialRevalidateSeconds =
3086
- exportConfig . initialPageRevalidationMap [ route ]
3111
+ pageInfo . initialRevalidateSeconds = initialRevalidateSeconds
3087
3112
}
3088
3113
}
3089
3114
}
@@ -3296,7 +3321,7 @@ export default async function build(
3296
3321
)
3297
3322
if ( appDir ) {
3298
3323
const originalServerApp = path . join ( distDir , SERVER_DIRECTORY , 'app' )
3299
- if ( fsExistsSync ( originalServerApp ) ) {
3324
+ if ( await fileExists ( originalServerApp ) ) {
3300
3325
await recursiveCopy (
3301
3326
originalServerApp ,
3302
3327
path . join (
@@ -3353,8 +3378,7 @@ export default async function build(
3353
3378
}
3354
3379
3355
3380
if ( config . output === 'export' ) {
3356
- const exportApp : typeof import ( '../export' ) . default =
3357
- require ( '../export' ) . default
3381
+ const exportApp : ExportAppWorker = require ( '../export' ) . default
3358
3382
3359
3383
const pagesWorker = createStaticWorker (
3360
3384
incrementalCacheIpcPort ,
@@ -3365,7 +3389,7 @@ export default async function build(
3365
3389
incrementalCacheIpcValidationKey
3366
3390
)
3367
3391
3368
- const options : ExportOptions = {
3392
+ const options : ExportAppOptions = {
3369
3393
isInvokedFromCli : false ,
3370
3394
buildExport : false ,
3371
3395
nextConfig : config ,
0 commit comments