From b69dac121ac6b9d72d1eae9da5db5cd4f1dcc334 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 2 Nov 2022 16:16:59 +0100 Subject: [PATCH] Fix page folder being wrongly resolved as page file (#42348) Closes #42010. ## Bug - [ ] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- .../build/webpack/loaders/next-app-loader.ts | 19 +++++++++++++------ .../app-dir/app/app/dashboard/page/page.jsx | 7 +++++++ test/e2e/app-dir/index.test.ts | 5 +++++ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 test/e2e/app-dir/app/app/dashboard/page/page.jsx diff --git a/packages/next/build/webpack/loaders/next-app-loader.ts b/packages/next/build/webpack/loaders/next-app-loader.ts index 0e428687b0b2b13..d5191c03ac2efd6 100644 --- a/packages/next/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/build/webpack/loaders/next-app-loader.ts @@ -17,6 +17,8 @@ export const FILE_TYPES = { 'not-found': 'not-found', } as const +const PAGE_SEGMENT = 'page$' + // TODO-APP: check if this can be narrowed. type ComponentModule = () => any export type ComponentsType = { @@ -59,10 +61,8 @@ async function createTreeCodeFromPath({ } for (const [parallelKey, parallelSegment] of parallelSegments) { - const parallelSegmentPath = segmentPath + '/' + parallelSegment - - if (parallelSegment === 'page') { - const matchedPagePath = `${appDirPrefix}${parallelSegmentPath}` + if (parallelSegment === PAGE_SEGMENT) { + const matchedPagePath = `${appDirPrefix}${segmentPath}/page` const resolvedPagePath = await resolve(matchedPagePath) if (resolvedPagePath) pages.push(resolvedPagePath) @@ -73,6 +73,7 @@ async function createTreeCodeFromPath({ continue } + const parallelSegmentPath = segmentPath + '/' + parallelSegment const subtree = await createSubtreePropsFromSegmentPath([ ...segments, parallelSegment, @@ -175,12 +176,18 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{ const matched: Record = {} for (const path of normalizedAppPaths) { if (path.startsWith(pathname + '/')) { - const restPath = path.slice(pathname.length + 1) + const rest = path.slice(pathname.length + 1).split('/') + + let matchedSegment = rest[0] + // It is the actual page, mark it sepcially. + if (rest.length === 1 && matchedSegment === 'page') { + matchedSegment = PAGE_SEGMENT + } - const matchedSegment = restPath.split('/')[0] const matchedKey = matchedSegment.startsWith('@') ? matchedSegment.slice(1) : 'children' + matched[matchedKey] = matchedSegment } } diff --git a/test/e2e/app-dir/app/app/dashboard/page/page.jsx b/test/e2e/app-dir/app/app/dashboard/page/page.jsx new file mode 100644 index 000000000000000..d328445b834cf44 --- /dev/null +++ b/test/e2e/app-dir/app/app/dashboard/page/page.jsx @@ -0,0 +1,7 @@ +export default function DashboardPagePage() { + return ( + <> +

hello dashboard/page!

+ + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 338dd701459237f..b589356462eebbf 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -292,6 +292,11 @@ describe('app dir', () => { ) }) + it('should serve page as a segment name correctly', async () => { + const html = await renderViaHTTP(next.url, '/dashboard/page') + expect(html).toContain('hello dashboard/page!') + }) + it('should include document html and body', async () => { const html = await renderViaHTTP(next.url, '/dashboard') const $ = cheerio.load(html)