@@ -7,6 +7,7 @@ import { sep } from 'path'
77import { verifyRootLayout } from '../../../lib/verifyRootLayout'
88import * as Log from '../../../build/output/log'
99import { APP_DIR_ALIAS } from '../../../lib/constants'
10+ import { resolveFileBasedMetadataForLoader } from '../../../lib/metadata/resolve-metadata'
1011
1112const FILE_TYPES = {
1213 layout : 'layout' ,
@@ -36,21 +37,26 @@ async function createTreeCodeFromPath({
3637 resolveParallelSegments,
3738} : {
3839 pagePath : string
39- resolve : ( pathname : string ) => Promise < string | undefined >
40+ resolve : (
41+ pathname : string ,
42+ resolveDir ?: boolean
43+ ) => Promise < string | undefined >
4044 resolveParallelSegments : (
4145 pathname : string
4246 ) => [ key : string , segment : string ] [ ]
4347} ) {
4448 const splittedPath = pagePath . split ( / [ \\ / ] / )
4549 const appDirPrefix = splittedPath [ 0 ]
4650 const pages : string [ ] = [ ]
51+
4752 let rootLayout : string | undefined
4853 let globalError : string | undefined
4954
5055 async function createSubtreePropsFromSegmentPath (
5156 segments : string [ ]
5257 ) : Promise < {
5358 treeCode : string
59+ treeMetadataCode : string
5460 } > {
5561 const segmentPath = segments . join ( '/' )
5662
@@ -65,12 +71,26 @@ async function createTreeCodeFromPath({
6571 parallelSegments . push ( ...resolveParallelSegments ( segmentPath ) )
6672 }
6773
74+ let metadataCode = ''
75+
6876 for ( const [ parallelKey , parallelSegment ] of parallelSegments ) {
6977 if ( parallelSegment === PAGE_SEGMENT ) {
7078 const matchedPagePath = `${ appDirPrefix } ${ segmentPath } /page`
7179 const resolvedPagePath = await resolve ( matchedPagePath )
7280 if ( resolvedPagePath ) pages . push ( resolvedPagePath )
7381
82+ metadataCode += `{
83+ type: 'page',
84+ layer: ${
85+ // There's an extra virtual segment.
86+ segments . length - 1
87+ } ,
88+ mod: () => import(/* webpackMode: "eager" */ ${ JSON . stringify (
89+ resolvedPagePath
90+ ) } ),
91+ path: ${ JSON . stringify ( resolvedPagePath ) } ,
92+ },`
93+
7494 // Use '' for segment as it's the page. There can't be a segment called '' so this is the safest way to add it.
7595 props [ parallelKey ] = `['', {}, {
7696 page: [() => import(/* webpackMode: "eager" */ ${ JSON . stringify (
@@ -80,9 +100,8 @@ async function createTreeCodeFromPath({
80100 }
81101
82102 const parallelSegmentPath = segmentPath + '/' + parallelSegment
83- const { treeCode : subtreeCode } = await createSubtreePropsFromSegmentPath (
84- [ ...segments , parallelSegment ]
85- )
103+ const { treeCode : subtreeCode , treeMetadataCode : subTreeMetadataCode } =
104+ await createSubtreePropsFromSegmentPath ( [ ...segments , parallelSegment ] )
86105
87106 // `page` is not included here as it's added above.
88107 const filePaths = await Promise . all (
@@ -101,6 +120,27 @@ async function createTreeCodeFromPath({
101120 rootLayout = layoutPath
102121 }
103122
123+ // Collect metadata for the layout
124+ if ( layoutPath ) {
125+ metadataCode += `{
126+ type: 'layout',
127+ layer: ${ segments . length } ,
128+ mod: () => import(/* webpackMode: "eager" */ ${ JSON . stringify (
129+ layoutPath
130+ ) } ),
131+ path: ${ JSON . stringify ( layoutPath ) } ,
132+ },`
133+ }
134+ metadataCode += await resolveFileBasedMetadataForLoader (
135+ segments . length ,
136+ ( await resolve ( `${ appDirPrefix } ${ parallelSegmentPath } /` , true ) ) !
137+ )
138+ metadataCode += subTreeMetadataCode
139+
140+ if ( ! rootLayout ) {
141+ rootLayout = layoutPath
142+ }
143+
104144 if ( ! globalError ) {
105145 globalError = await resolve (
106146 `${ appDirPrefix } ${ parallelSegmentPath } /${ GLOBAL_ERROR_FILE_TYPE } `
@@ -133,13 +173,16 @@ async function createTreeCodeFromPath({
133173 . map ( ( [ key , value ] ) => `${ key } : ${ value } ` )
134174 . join ( ',\n' ) }
135175 }` ,
176+ treeMetadataCode : metadataCode ,
136177 }
137178 }
138179
139- const { treeCode } = await createSubtreePropsFromSegmentPath ( [ ] )
180+ const { treeCode, treeMetadataCode } =
181+ await createSubtreePropsFromSegmentPath ( [ ] )
140182 return {
141183 treeCode : `const tree = ${ treeCode } .children;` ,
142- pages,
184+ treeMetadataCode : `const metadata = [${ treeMetadataCode } ];` ,
185+ pages : `const pages = ${ JSON . stringify ( pages ) } ;` ,
143186 rootLayout,
144187 globalError,
145188 }
@@ -197,7 +240,7 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
197240 const rest = path . slice ( pathname . length + 1 ) . split ( '/' )
198241
199242 let matchedSegment = rest [ 0 ]
200- // It is the actual page, mark it sepcially .
243+ // It is the actual page, mark it specially .
201244 if ( rest . length === 1 && matchedSegment === 'page' ) {
202245 matchedSegment = PAGE_SEGMENT
203246 }
@@ -212,7 +255,11 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
212255 return Object . entries ( matched )
213256 }
214257
215- const resolver = async ( pathname : string ) => {
258+ const resolver = async ( pathname : string , resolveDir ?: boolean ) => {
259+ if ( resolveDir ) {
260+ return createAbsolutePath ( appDir , pathname )
261+ }
262+
216263 try {
217264 const resolved = await resolve ( this . rootContext , pathname )
218265 this . addDependency ( resolved )
@@ -230,12 +277,17 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
230277 }
231278 }
232279
233- const { treeCode, pages, rootLayout, globalError } =
234- await createTreeCodeFromPath ( {
235- pagePath,
236- resolve : resolver ,
237- resolveParallelSegments,
238- } )
280+ const {
281+ treeCode,
282+ treeMetadataCode,
283+ pages : pageListCode ,
284+ rootLayout,
285+ globalError,
286+ } = await createTreeCodeFromPath ( {
287+ pagePath,
288+ resolve : resolver ,
289+ resolveParallelSegments,
290+ } )
239291
240292 if ( ! rootLayout ) {
241293 const errorMessage = `${ chalk . bold (
@@ -263,7 +315,8 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
263315
264316 const result = `
265317 export ${ treeCode }
266- export const pages = ${ JSON . stringify ( pages ) }
318+ export ${ treeMetadataCode }
319+ export ${ pageListCode }
267320
268321 export { default as AppRouter } from 'next/dist/client/components/app-router'
269322 export { default as LayoutRouter } from 'next/dist/client/components/layout-router'
0 commit comments