Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix client reference manifest for interception routes #52961

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 28 additions & 16 deletions packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,32 @@ function getAppPathRequiredChunks(chunkGroup: webpack.ChunkGroup) {
.filter(nonNullable)
}

// Normalize the entry names to their "group names" so a page can easily track
// all the manifest items it needs from parent groups by looking up the group
// segments:
// - app/foo/loading -> app/foo
// - app/foo/page -> app/foo
// - app/(group)/@named/foo/page -> app/foo
// - app/(.)foo/(..)bar/loading -> app/bar
function entryNameToGroupName(entryName: string) {
let groupName = entryName
.slice(0, entryName.lastIndexOf('/'))
.replace(/\/@[^/]+/g, '')
.replace(/\/\([^/]+\)(\/|$)/g, '$2')

// Interception routes
groupName = groupName
.replace(/^.+\/\(\.\.\.\)/g, 'app/')
.replace(/\/\(\.\)/g, '/')

// Interception routes (recursive)
while (/\/[^/]+\/\(\.\.\)/.test(groupName)) {
groupName = groupName.replace(/\/[^/]+\/\(\.\.\)/g, '/')
}

return groupName
}

function mergeManifest(
manifest: ClientReferenceManifest,
manifestToMerge: ClientReferenceManifest
Expand Down Expand Up @@ -344,24 +370,13 @@ export class ClientReferenceManifestPlugin {
manifestEntryFiles.push('app/not-found')
}

// Group the entry by their route path, so the page has all manifest items
// it needs:
// - app/foo/loading -> app/foo
// - app/foo/page -> app/foo
// - app/(group)/@named/foo/page -> app/foo
const groupName = entryName
.slice(0, entryName.lastIndexOf('/'))
.replace(/\/@[^/]+/g, '')
.replace(/\/\([^/]+\)/g, '')

const groupName = entryNameToGroupName(entryName)
if (!manifestsPerGroup.has(groupName)) {
manifestsPerGroup.set(groupName, [])
}
manifestsPerGroup.get(groupName)!.push(manifest)
})

// console.log(manifestEntryFiles, manifestsPerGroup)

// Generate per-page manifests.
for (const pageName of manifestEntryFiles) {
const mergedManifest: ClientReferenceManifest = {
Expand All @@ -371,12 +386,9 @@ export class ClientReferenceManifestPlugin {
entryCSSFiles: {},
}

const segments = pageName.split('/')
const segments = [...entryNameToGroupName(pageName).split('/'), 'page']
let group = ''
for (const segment of segments) {
if (segment.startsWith('@')) continue
if (segment.startsWith('(') && segment.endsWith(')')) continue

for (const manifest of manifestsPerGroup.get(group) || []) {
mergeManifest(mergedManifest, manifest)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use client'

import { useState } from 'react'

export function Client() {
const value = useState('client component')[0]
return <p id="interception-slot-client">{value}</p>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React from 'react'
import { Client } from './client'

export default function Page() {
return <p id="interception-slot">interception from @slot/nested</p>
return (
<>
<p id="interception-slot">interception from @slot/nested</p>
<Client />
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,12 @@ createNextDescribe(
'interception from @slot/nested'
)

// Check if the client component is rendered
await check(
() => browser.waitForElementByCss('#interception-slot-client').text(),
'client component'
)

await check(
() => browser.refresh().waitForElementByCss('#nested').text(),
'hello world from /nested'
Expand Down