Skip to content

Commit

Permalink
Remove dependency on the default parallel route
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Jul 24, 2023
1 parent 605c0cd commit a63bab7
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 114 deletions.
22 changes: 12 additions & 10 deletions packages/next-swc/crates/next-core/src/app_structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,16 +675,18 @@ async fn directory_tree_to_entrypoints_internal(
LoaderTree {
segment: directory_name.to_string(),
parallel_routes: indexmap! {
"children".to_string() => LoaderTree {
segment: "__DEFAULT__".to_string(),
parallel_routes: IndexMap::new(),
components: Components {
default: Some(get_next_package(app_dir).join("dist/client/components/parallel-route-default.js".to_string())),
..Default::default()
}
.cell(),
}
.cell(),
// TODO(alexkirsz) Next.js has a __DEFAULT__ entry for
// next/dist/client/components/parallel-route-default here only for parallel routes with slots.
// "children".to_string() => LoaderTree {
// segment: "__DEFAULT__".to_string(),
// parallel_routes: IndexMap::new(),
// components: Components {
// default: Some(get_next_package(app_dir).join("dist/client/components/parallel-route-default.js".to_string())),
// ..Default::default()
// }
// .cell(),
// }
// .cell(),
},
components: components.without_leafs().cell(),
}
Expand Down
24 changes: 15 additions & 9 deletions packages/next/src/build/webpack/loaders/next-app-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ async function createTreeCodeFromPath(
const adjacentParallelSegments = await resolveAdjacentParallelSegments(
segmentPath
)
const hasOnlyChildrenRoutes =
adjacentParallelSegments.length === 1 &&
adjacentParallelSegments[0] === 'children'

for (const adjacentParallelSegment of adjacentParallelSegments) {
if (!props[normalizeParallelKey(adjacentParallelSegment)]) {
Expand All @@ -401,15 +404,18 @@ async function createTreeCodeFromPath(
`${appDirPrefix}${segmentPath}/${actualSegment}/default`
)) ?? 'next/dist/client/components/parallel-route-default'

props[normalizeParallelKey(adjacentParallelSegment)] = `[
'__DEFAULT__',
{},
{
defaultPage: [() => import(/* webpackMode: "eager" */ ${JSON.stringify(
defaultPath
)}), ${JSON.stringify(defaultPath)}],
}
]`
// __DEFAULT__ should only occur in the parallel routes when slots are presented
if (!hasOnlyChildrenRoutes) {
props[normalizeParallelKey(adjacentParallelSegment)] = `[
'__DEFAULT__',
{},
{
defaultPage: [() => import(/* webpackMode: "eager" */ ${JSON.stringify(
defaultPath
)}), ${JSON.stringify(defaultPath)}],
}
]`
}
}
}
return {
Expand Down
11 changes: 2 additions & 9 deletions packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -944,20 +944,13 @@ export async function renderToHTMLOrFlight(

// If it's a not found route, and we don't have any matched parallel
// routes, we try to render the not found component if it exists.
const isNotFoundTreeNode =
process.env.NODE_ENV !== 'development'
? // In build mode, the 'not-found' segment doesn't have any parallel routes
!segment && !rootLayoutIncluded
: // In dev mode, hitting the routes that don't exist will resolve with the tree that parallel-route-default
!parallelRouteMap.length && segment === '__DEFAULT__'

let notFoundComponent = {}
if (
NotFound &&
// For action not-found we force render the NotFound and stop checking the parallel routes.
(asNotFound === 'force' ||
// For normal case where we should look up for not-found, keep checking the parallel routes.
(asNotFound && isNotFoundTreeNode))
(asNotFound && !parallelRouteMap.length))
) {
notFoundComponent = {
children: (
Expand Down Expand Up @@ -1704,7 +1697,7 @@ export async function renderToHTMLOrFlight(
)

const notFoundLoaderTree: LoaderTree = is404
? ['__DEFAULT__', {}, loaderTree[2]]
? ['', {}, loaderTree[2]]
: loaderTree

const initialTree = createFlightRouterStateFromLoaderTree(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,104 +1,119 @@
import { createNextDescribe } from 'e2e-utils'

createNextDescribe(
'not-found-linking',
{
files: __dirname,
},
({ next }) => {
it('should allow navigation on not-found', async () => {
const browser = await next.browser('/trigger-404')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

expect(
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.text()
).toBe('Result Page!')
})

it('should allow navigation on error', async () => {
const browser = await next.browser('/trigger-error')
expect(await browser.elementByCss('#error-component').text()).toBe(
'Error Happened!'
)

expect(
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.text()
).toBe('Result Page!')
})

it('should allow navigation to other routes on route that was initially not-found', async () => {
// Intentionally non-existent route.
const browser = await next.browser('/testabc')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

expect(
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.text()
).toBe('Result Page!')
})

it('should allow navigation back to route that was initially not-found', async () => {
// Intentionally non-existent route.
const browser = await next.browser('/testabc')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

function runTest({ next }) {
it('should allow navigation on not-found', async () => {
const browser = await next.browser('/trigger-404')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

expect(
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.back()
.waitForElementByCss('#not-found-component')
})
.text()
).toBe('Result Page!')
})

it('should allow navigating to a page calling notfound', async () => {
const browser = await next.browser('/')
it('should allow navigation on error', async () => {
const browser = await next.browser('/trigger-error')
expect(await browser.elementByCss('#error-component').text()).toBe(
'Error Happened!'
)

expect(
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.text()
).toBe('Result Page!')
})

it('should allow navigation to other routes on route that was initially not-found', async () => {
// Intentionally non-existent route.
const browser = await next.browser('/testabc')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

expect(
await browser
.elementByCss('#trigger-404-link')
.elementByCss('#to-result')
.click()
.waitForElementByCss('#not-found-component')
.waitForElementByCss('#result-page')
.text()
).toBe('Result Page!')
})

expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)
it('should allow navigation back to route that was initially not-found', async () => {
// Intentionally non-existent route.
const browser = await next.browser('/testabc')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

await browser.back().waitForElementByCss('#homepage')
await browser
.elementByCss('#to-result')
.click()
.waitForElementByCss('#result-page')
.back()
.waitForElementByCss('#not-found-component')
})

expect(await browser.elementByCss('#homepage').text()).toBe('Home')
})
it('should allow navigating to a page calling notfound', async () => {
const browser = await next.browser('/')

it('should allow navigating to a non-existent page', async () => {
const browser = await next.browser('/')
await browser
.elementByCss('#trigger-404-link')
.click()
.waitForElementByCss('#not-found-component')

await browser
.elementByCss('#non-existent-link')
.click()
.waitForElementByCss('#not-found-component')
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

await browser.back().waitForElementByCss('#homepage')

expect(await browser.elementByCss('#homepage').text()).toBe('Home')
})

expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)
it('should allow navigating to a non-existent page', async () => {
const browser = await next.browser('/')

await browser.back().waitForElementByCss('#homepage')
await browser
.elementByCss('#non-existent-link')
.click()
.waitForElementByCss('#not-found-component')

expect(await browser.elementByCss('#homepage').text()).toBe('Home')
})
expect(await browser.elementByCss('#not-found-component').text()).toBe(
'Not Found!'
)

await browser.back().waitForElementByCss('#homepage')

expect(await browser.elementByCss('#homepage').text()).toBe('Home')
})
}

createNextDescribe(
'app dir - not found navigation',
{
files: __dirname,
},
({ next }) => {
runTest({ next })
}
)

createNextDescribe(
'app dir - not found navigation - with overridden node env',
{
files: __dirname,
env: { NODE_ENV: 'test' },
},
({ next }) => {
runTest({ next })
}
)
2 changes: 1 addition & 1 deletion test/lib/next-modes/next-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class NextDevInstance extends NextInstance {
env: {
...process.env,
...this.env,
NODE_ENV: '' as any,
NODE_ENV: this.env.NODE_ENV || ('' as any),
PORT: this.forcedPort || '0',
__NEXT_TEST_MODE: 'e2e',
__NEXT_TEST_WITH_DEVTOOL: '1',
Expand Down
2 changes: 1 addition & 1 deletion test/lib/next-modes/next-start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class NextStartInstance extends NextInstance {
env: {
...process.env,
...this.env,
NODE_ENV: '' as any,
NODE_ENV: this.env.NODE_ENV || ('' as any),
PORT: this.forcedPort || '0',
__NEXT_TEST_MODE: 'e2e',
},
Expand Down

0 comments on commit a63bab7

Please sign in to comment.